Passing a character array as a parameter (C kernel code)

I am trying to print something on the screen using my print function. A.

I came across a small problem - when I pass an array of characters as follows:

char s[] = "abc"; print(s); 

It works fine, but when I call it, it does not affect.

 print("abc"); 

Here is my function declaration

 //print function void print(char* message); 

Am I missing something? printf works the same way, and you can pass the string in the second way.

EDIT:

Definitions

 void print_at(char* message, int col, int row){ if(col >= 0 && row >= 0){ set_cursor(get_screen_offset(col,row)); } int i = 0; while(message[i] != 0){ print_char(message[i++],-1,-1,WHITE_ON_BLACK); } } void print(char* message){ print_at(message, -1,-1); } 

EDIT2: objdump kernel .o

 void start(){ clear_screen(); char s[] = "abc"; print("abc"); print(s); while(1); } 

Dismantling the .text section:

 00000000 <_start>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 83 ec 28 sub esp,0x28 6: e8 00 00 00 00 call b <_start+0xb> //clear_screen() b: c7 45 f4 61 62 63 00 mov DWORD PTR [ebp-0xc],0x636261 //"bca" 12: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0 19: e8 00 00 00 00 call 1e <_start+0x1e> //print() 1e: 8d 45 f4 lea eax,[ebp-0xc] 21: 89 04 24 mov DWORD PTR [esp],eax 24: e8 00 00 00 00 call 29 <_start+0x29> //print() 29: eb fe jmp 29 <_start+0x29> 2b: 90 nop 

EDIT3:

Since this may be something with the way I initialize the environment, here are 2 files that are responsible:

pmode.asm - initializes segments and jumps to the beginning of the kernel

 [bits 16] switch_to_pm: cli ; switch interuppts off lgdt [gdt_descriptor] ; load global descriptor table mov eax, cr0 ; set control registers first bit to protected mode or eax, 0x1 mov cr0, eax jmp CODE_SEG:init_pm ;flush cache by far jump [bits 32] init_pm: mov ax, DATA_SEG mov ds, ax mov ss, ax mov es, ax mov fs, ax mov gs, ax mov ebp, 0x90000 mov esp, ebp call BEGIN_PM 

this is how i build gdt:

; Gdt

 gdt_start: gdt_null: ; the mandatory null descriptor dd 0x0 ; ' dd ' means define double word ( ie 4 bytes ) dd 0x0 gdt_code: ; the code segment descriptor ; base =0 x0 , limit =0 xfffff , ; 1 st flags : ( present )1 ( privilege )00 ( descriptor type )1 -> 1001 b ; type flags : ( code )1 ( conforming )0 ( readable )1 ( accessed )0 -> 1010 b ; 2 nd flags : ( granularity )1 (32- bit default )1 (64- bit seg )0 ( AVL )0 -> 1100 b dw 0xffff ; Limit ( bits 0-15) dw 0x0 ; Base ( bits 0-15) db 0x0 ; Base ( bits 16-23) db 10011010b ; 1 st flags , type flags db 11001111b ; 2 nd flags , Limit ( bits 16-19) db 0x0 ; Base ( bits 24-31) gdt_data: ; the data segment descriptor ; Same as code segment except for the type flags : ; type flags : ( code )0 ( expand down )0 ( writable )1 ( accessed )0 -> 0010 b dw 0xffff ; Limit ( bits 0-15) dw 0x0 ; Base ( bits 0-15) db 0x0 ; Base ( bits 16-23) db 10010010b ; 1 st flags , type flags db 11001111b ; 2 nd flags , Limit ( bits 16-19) db 0x0 ; Base ( bits 24-31) gdt_end: ; The reason for putting a label at the end of the ; GDT is so we can have the assembler calculate ; the size of the GDT for the GDT decriptor ( below ) ; GDT descriptior gdt_descriptor: dw gdt_end - gdt_start - 1 ; Size of our GDT , always less one ; of the true size dd gdt_start ; Start address of our GDT ; Define some handy constants for the GDT segment descriptor offsets , which ; are what segment registers must contain when in protected mode. For example , ; when we set DS = 0 x10 in PM , the CPU knows that we mean it to use the ; segment described at offset 0 x10 ( ie 16 bytes ) in our GDT , which in our ; case is the DATA segment (0 x0 -> NULL ; 0 x08 -> CODE ; 0 x10 -> DATA ) CODE_SEG equ gdt_code - gdt_start DATA_SEG equ gdt_data - gdt_start 
+6
source share
2 answers

I found the answer by looking at a disassembly with a much larger string.

The reason was how I connected the core. These were the commands that I was advised to use:

 ld -o kernel.bin -Ttext 0x1000 $^ --oformat binary 

but since I had gcc windows and my asm and C files were in elf format, I had to use this trick:

 ld -o kernel.out -Ttext 0x1000 $^ objcopy -O binary -j .text kernel.out $@ 

This only copied the text part of the object, so I stayed with the binary version. Since I just copied the .text part of the object, my lines that were contained in the .rdata strong> sections were lost. So this is just a matter of adding this to objcopy:

 objcopy -O binary -j .text -j .rdata kernel.out $@ 
+1
source

When you say print (s), you pass it as an array of char beacuse, which you declared "s". But when you go through printing ("abc"). What is the type of "abc". This is not defined. I think this is your problem. I also recommend that you change your char s [] to char * s. Hope this helps.

-1
source

Source: https://habr.com/ru/post/951506/


All Articles