String literals not working

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
finlaymorrison
Posts: 1
Joined: Fri Jan 29, 2021 1:37 am

String literals not working

Post by finlaymorrison »

I am pretty new to OS dev, and I am trying to get some text to print out some text. It seems that if I pass a string to a function, it gets turned into nullchars, for example the code below:

```c
#include "../drivers/ports.h"
#include "../drivers/screen.h"

void print_first_char(char* str)
{
print_char(str[0], 0, 10, WHITE_ON_BLACK);
}

void kernel_main()
{
clear_screen();

char* str = "rewqtqrewqre";
print_char(str[0], 0, 10, WHITE_ON_BLACK);

print_first_char(str);
}
```

Will sucsessfuly print the 'r' character when the `print_first_char` function is commented out, however upon uncommenting it it no longer works,

I also found that looping through a string with a for loop does not work, in the following code, the top block works fine, and the bottom one does not.

```c
void kernel_main()
{
clear_screen();

char* str = "rewqtqrewqre";

print_char(str[0], 0, 10, WHITE_ON_BLACK);
print_char(str[1], 1, 10, WHITE_ON_BLACK);
print_char(str[2], 2, 10, WHITE_ON_BLACK);
print_char(str[3], 3, 10, WHITE_ON_BLACK);
print_char(str[4], 4, 10, WHITE_ON_BLACK);
print_char(str[5], 5, 10, WHITE_ON_BLACK);
}
```
and this code does not work:
```c
void kernel_main()
{
clear_screen();

char* str = "rewqtqrewqre";

for (int i = 0; i < 6; ++i)
{
print_char(str, i, 10, WHITE_ON_BLACK);
}
}
```

Any info for why this may not work would be greatly appreciated, if you would like to see more of the code my github repo is here: https://github.com/finlaymorrison/os
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: String literals not working

Post by Octocontrabass »

How many sectors is your kernel binary?

How many sectors does your bootloader load?
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: String literals not working

Post by neon »

Hi,

You are pushing 2 bytes for all ISRs yet popping 8 before IRET. Same error occurs with IRQ. Either do add esp, 2 or push dword instead of push byte. To ensure stack alignment, I recommend pushing dword. Farther if you are going to use STI, make sure the timer is enabled prior. I advise disabling it for now (CLI or just remove the STI's from the code.) Also need to emphasize not to copy and paste code unless you know precisely what it does.

Code: Select all

isr0:
    cli
    push byte 0
    push byte 0      <--
    jmp isr_common_stub

isr_common_stub:
    pusha

    mov ax, ds
    push eax
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    call isr_handler

    pop eax
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    popa

    add esp, 8    <--
    sti     <--
    iret
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: String literals not working

Post by Octocontrabass »

neon wrote:You are pushing 2 bytes for all ISRs yet popping 8 before IRET.
PUSH doesn't support byte operands. In this case, NASM will treat the "byte" keyword as an optimization hint instead of the operand size.

I recommend deleting the "byte" keyword and relying on NASM's optimizer to choose the smallest instruction encoding. There's no need to specify the operand size, since it's already dword by default.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: String literals not working

Post by neon »

Hi,

I believe you are right -- I was confusing instruction length without considering the CPU zero or sign extending the operand so this might be alright. The instruction itself supports imm8 -- 6a[imm8] -- but it appears to sign extend it to the operating mode size prior to pushing to the stack.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply