Why can't I make a char array longer than 61 characters in C? [duplicate]

限于喜欢 提交于 2020-04-07 05:27:14

问题


I'm following this tutorial to make a simple bare bones 32-bit operating system. I have gotten as far as section 4 where i'm writing to the frame buffer. Basically i'm attempting to create my own println function. Here is the code for my function:

/** fb_write_cell:
 * Writes a character with the given foreground and background to position i
 * in the framebuffer.
 *
 * @param i The location in the framebuffer
 * @param c The character
 * @param fg The foreground color
 * @param bg The background color
 */
static void fb_write_cell(unsigned int i, char c, unsigned char fg, unsigned bg) {
  fb[i] = c;
  fb[i + 1] = ((fg & 0x0F) << 4) | (bg & 0x0F);
}

/** fb_print:
 * Print a string of text to the framebuffer
 * @param *buf The character array to print
 */
int fb_print(char *str, unsigned int length) {
  unsigned int i = 0, x = 0;

  // print the message to the framebuffer
  for(; i < (2 * length); i+=2) {
    fb_write_cell(i, str[x], FB_BLACK, FB_GREEN);
    x++;
  }
  return 0;
}

/** fb_println:
 * Print a string of text to the framebuffer and move to the next line
 * @param *buf The character array to print
 */
int fb_println(char *str, unsigned int length) {
   fb_print(str, length);

  return 0;
}

I call it like this:

char array[] = "Hello world!";
fb_println(array, sizeof(array));

However if I make the array longer than 61 characters I stop getting any output to the screen. In fact any code after the array creation doesn't get executed. I'm thinking that maybe it has something to do with limited RAM in my bare system (maybe only 64 bytes?) but I'm not sure.

My multiboot header and startup code in loader.s that calls my C entry point main is:

global loader                   ; the entry symbol for ELF

MAGIC_NUMBER equ 0x1BADB002     ; define the magic number constant
FLAGS        equ 0x0            ; multiboot flags
CHECKSUM     equ -MAGIC_NUMBER  ; calculate the checksum
                                ; (magic number + checksum + flags should equal 0)

KERNEL_STACK_SIZE equ 4096      ; size of stack in bytes

extern sum_of_three             ; the function is defined elsewhere
extern main

section .text:                  ; start of the text (code) section
align 4                         ; the code must be 4 byte aligned
    dd MAGIC_NUMBER             ; write the magic number to the machine code,
    dd FLAGS                    ; the flags,
    dd CHECKSUM                 ; and the checksum

section .bss:
align 4                     ; align at 4 bytes
kernel_stack:               ; label points to beginning of memory
    resb KERNEL_STACK_SIZE  ; reserve stack for the kernel

loader:                                           ; the loader label (defined as entry point in linker script)
    mov eax, 0xCAFEBABE                           ; place the number 0xCAFEBABE in the register eax
    mov esp, kernel_stack + KERNEL_STACK_SIZE     ; point esp to the start of the
                                                  ; stack (end of memory area)
    ;Example of how to call a function and send args
    ;push dword 3                                  ; arg3
    ;push dword 2                                  ; arg2
    ;push dword 1                                  ; arg1
    ;call sum_of_three                             ; call the function, the result will be in EAX


.loop:
    call main
    jmp .loop                   ; loop forever

My linker script link.ld is:

ENTRY(loader)                /* the name of the entry label */

SECTIONS {
    . = 0x00100000;          /* the code should be loaded at 1 MB */

    .text ALIGN (0x1000) :   /* align at 4 KB */
    {
        *(.text)             /* all text sections from all files */
    }

    .rodata ALIGN (0x1000) : /* align at 4 KB */
    {
        *(.rodata*)          /* all read-only data sections from all files */
    }

    .data ALIGN (0x1000) :   /* align at 4 KB */
    {
        *(.data)             /* all data sections from all files */
    }

    .bss ALIGN (0x1000) :    /* align at 4 KB */
    {
        *(COMMON)            /* all COMMON sections from all files */
        *(.bss)              /* all bss sections from all files */
    }
}

My whole source code can be found here.


回答1:


The issues here are not related to your C code but problems in your file loader.s. You have problems with the section names having a colon on the end that becomes part of the section name, and you haven't put the code in the executable .text section.

These lines have extra colons on the section names:

section .text:                  ; start of the text (code) section

section .bss:

They should be:

section .text                   ; start of the text (code) section

section .bss

These extra colons cause things to be placed in unexpected way and could be influenced by the amount of data in a particular section (like strings in your C code). This likely caused your kernel.elf to not always appear as a Multiboot compatible bootloader.

As well code needs to be placed in the .text section. You placed your stack and the code after it in the .bss section which is incorrect. To fix this place a section directive above the start of your code like this:

section .text
loader:                        ; the loader label (defined as entry point in linker script)

You also put your kernel in an infinite loop:

.loop:
    call main
    jmp .loop                   ; loop forever

You probably meant to put an infinite loop after your kernel is complete:

    call main
.loop:
    jmp .loop                   ; loop forever

Error in LittleOS Book Tutorial

I noticed that this seems to be a mistake on the part of the author of the tutorial you are using in the section Compiling the Operating System as the mistake appears in this code:

section .text:                  ; start of the text (code) section
align 4                         ; the code must be 4 byte aligned

Someone may wish to raise this issue with the author.



来源:https://stackoverflow.com/questions/46759903/why-cant-i-make-a-char-array-longer-than-61-characters-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!