GCC + NASM in linux
Posted: Sat Jan 24, 2004 12:00 am
Hi!
I'm tryng to link ASM code to a C program for writing a somewhat kernel.
------[kernel.c start]------
extern void hi(void);
extern void quit(void);
int main(){
hi();
quit();
}
------[kernel.c stop]------
------[plug.asm start]------
[BITS 32]
GLOBAL hi
GLOBAL quit
SECTION .text
hi: mov byte [es:0xb8f9c],'H'
mov byte [es:0xb8f9e],'i'
ret
quit: mov esp,ebp
pop ebp
retf
------[plug.asm stop]------
i compile it like this:
gcc -ffreestanding -c -o kernel.o kernel.c
nasm -f aout -o plug.o plug.asm
ld -Ttext 0x100000 --oformat binary -o kernel.bin kernel.o plug.o
but it crashes when it trys to run on FreeDOS or when i try to boot it.
(important to say that i bassed the code from: http://www.osdev.org/developers/guide01/index.jsp)
and what i have discovered is that is must be from the linker (LD) because e dissasambled the program and the CALLs go 2 bytes back from what they should be:
00000000 55 push bp
00000001 89E5 mov bp,sp
00000003 83EC08 sub sp,byte +0x8
00000006 83E4F0 and sp,byte -0x10
00000009 B80000 mov ax,0x0
0000000C 0000 add [bx+si],al
0000000E 29C4 sub sp,ax
00000010 E80B00 call 0x1e
00000013 0000 add [bx+si],al
00000015 E81700 call 0x2f
00000018 0000 add [bx+si],al
0000001A C9 leave
0000001B C3 ret
0000001C 90 nop
0000001D 90 nop
0000001E 90 nop
0000001F 90 nop
00000020 26C6059C mov byte [es:di],0x9c
00000024 8F db 0x8F
00000025 0B00 or ax,[bx+si]
00000027 48 dec ax
00000028 26C6059E mov byte [es:di],0x9e
0000002C 8F db 0x8F
0000002D 0B00 or ax,[bx+si]
0000002F 6989C3EC imul ax,bx,word 0xec89
00000033 5D pop bp
00000034 CB retf
00000035 90 nop
00000036 90 nop
00000037 90 nop
The first CALL goes to 0x1e when it should be 0x20 and the second call goes to 0x2f when it should (probably) go to 0x31.
Should the
[0000001A C9 leave]
[0000001B C3 ret]
really be there ?, when why so many NOPs ?
Is the problem from my linker (LD) ? or just me ? (probably the 2nd one)
I'm tryng to link ASM code to a C program for writing a somewhat kernel.
------[kernel.c start]------
extern void hi(void);
extern void quit(void);
int main(){
hi();
quit();
}
------[kernel.c stop]------
------[plug.asm start]------
[BITS 32]
GLOBAL hi
GLOBAL quit
SECTION .text
hi: mov byte [es:0xb8f9c],'H'
mov byte [es:0xb8f9e],'i'
ret
quit: mov esp,ebp
pop ebp
retf
------[plug.asm stop]------
i compile it like this:
gcc -ffreestanding -c -o kernel.o kernel.c
nasm -f aout -o plug.o plug.asm
ld -Ttext 0x100000 --oformat binary -o kernel.bin kernel.o plug.o
but it crashes when it trys to run on FreeDOS or when i try to boot it.
(important to say that i bassed the code from: http://www.osdev.org/developers/guide01/index.jsp)
and what i have discovered is that is must be from the linker (LD) because e dissasambled the program and the CALLs go 2 bytes back from what they should be:
00000000 55 push bp
00000001 89E5 mov bp,sp
00000003 83EC08 sub sp,byte +0x8
00000006 83E4F0 and sp,byte -0x10
00000009 B80000 mov ax,0x0
0000000C 0000 add [bx+si],al
0000000E 29C4 sub sp,ax
00000010 E80B00 call 0x1e
00000013 0000 add [bx+si],al
00000015 E81700 call 0x2f
00000018 0000 add [bx+si],al
0000001A C9 leave
0000001B C3 ret
0000001C 90 nop
0000001D 90 nop
0000001E 90 nop
0000001F 90 nop
00000020 26C6059C mov byte [es:di],0x9c
00000024 8F db 0x8F
00000025 0B00 or ax,[bx+si]
00000027 48 dec ax
00000028 26C6059E mov byte [es:di],0x9e
0000002C 8F db 0x8F
0000002D 0B00 or ax,[bx+si]
0000002F 6989C3EC imul ax,bx,word 0xec89
00000033 5D pop bp
00000034 CB retf
00000035 90 nop
00000036 90 nop
00000037 90 nop
The first CALL goes to 0x1e when it should be 0x20 and the second call goes to 0x2f when it should (probably) go to 0x31.
Should the
[0000001A C9 leave]
[0000001B C3 ret]
really be there ?, when why so many NOPs ?
Is the problem from my linker (LD) ? or just me ? (probably the 2nd one)