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
String literals not working
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: String literals not working
How many sectors is your kernel binary?
How many sectors does your bootloader load?
How many sectors does your bootloader load?
Re: String literals not working
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.
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();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: String literals not working
PUSH doesn't support byte operands. In this case, NASM will treat the "byte" keyword as an optimization hint instead of the operand size.neon wrote:You are pushing 2 bytes for all ISRs yet popping 8 before IRET.
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.
Re: String literals not working
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.
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();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}