Problem with binary-file of a compiled c-program
Posted: Fri Aug 24, 2007 11:18 am
Hello,
I wrote a small c-program to print 4 letters. I do not use any os-functions. The output is done by inline-assembling using the interrupt 10h.
I used borland's tcc and tlink to create the binary output file:
tcc -c shell.c
tlink /t /n /m shell.obj, out.bin
The c-program is defined as follows:
001 void printLetter( char p_byte ){
002
003 asm mov al, p_byte;
004 asm mov ah, 09h;
005 asm mov bh, 0;
006 asm mov bx, 112;
007 asm mov cx, 4;
008 asm int 10h;
009 }
010
011 void printString( char p_val[] ){
012
013 printLetter( p_val[1] );
014 }
015
016 int main( ) {
017
018 char* txt = "12";
019 printString( txt );
020 }
When I launch the program 4 letters are printed correctly, but
not the letter '2' as expected.
I tried to figure out what the problem is and disassembled out.bin:
printLetter:
00000000 55 push bp
00000001 8BEC mov bp,sp
00000003 8A4604 mov al,[bp+0x4]
00000006 B409 mov ah,0x9
00000008 B700 mov bh,0x0
0000000A BB7000 mov bx,0x70
0000000D B90400 mov cx,0x4
00000010 CD10 int 0x10
00000012 5D pop bp
00000013 C3 ret
printString:
00000014 55 push bp
00000015 8BEC mov bp,sp
00000017 8B5E04 mov bx,[bp+0x4]
0000001A FF7701 push word [bx+0x1]
0000001D E8E0FF call 0x0
00000020 59 pop cx
00000021 5D pop bp
00000022 C3 ret
main:
00000023 56 push si
00000024 BE0E00 mov si,0xe
00000027 56 push si
00000028 E8E9FF call 0x14
0000002B 59 pop cx
0000002C 5E pop si
0000002D C3 ret
datasegment:
0000002E 3132 xor [bp+si],si
00000030 00 db 0x00
printLetter and printString are ok. Call increases sp by a word and
bp is pushed onto stack at the function's beginning. Therefore [bp+0x4]
points to the right content.
If I open out.bin in a text-editor the string "12" is the last two chars
in file. This is similar to the linker's mapping output that locates the
datasegment at 2Eh as described in the disassembler's output above.
The thing I do not understand is what is done at address
00000024 BE0E00 mov si,0xe
00000027 56 push si
This is the value passed to printString as the address of parameter "txt".
What does 0xe mean? It neither can be the offset in the data-segment nor
is it a valid offset on stack. I think that is the reason why the printed
letter does not match the implemented one.
But what do I have to do to fix the bug ?
Can anybody help?
Thanks in advance.
Mathew
I wrote a small c-program to print 4 letters. I do not use any os-functions. The output is done by inline-assembling using the interrupt 10h.
I used borland's tcc and tlink to create the binary output file:
tcc -c shell.c
tlink /t /n /m shell.obj, out.bin
The c-program is defined as follows:
001 void printLetter( char p_byte ){
002
003 asm mov al, p_byte;
004 asm mov ah, 09h;
005 asm mov bh, 0;
006 asm mov bx, 112;
007 asm mov cx, 4;
008 asm int 10h;
009 }
010
011 void printString( char p_val[] ){
012
013 printLetter( p_val[1] );
014 }
015
016 int main( ) {
017
018 char* txt = "12";
019 printString( txt );
020 }
When I launch the program 4 letters are printed correctly, but
not the letter '2' as expected.
I tried to figure out what the problem is and disassembled out.bin:
printLetter:
00000000 55 push bp
00000001 8BEC mov bp,sp
00000003 8A4604 mov al,[bp+0x4]
00000006 B409 mov ah,0x9
00000008 B700 mov bh,0x0
0000000A BB7000 mov bx,0x70
0000000D B90400 mov cx,0x4
00000010 CD10 int 0x10
00000012 5D pop bp
00000013 C3 ret
printString:
00000014 55 push bp
00000015 8BEC mov bp,sp
00000017 8B5E04 mov bx,[bp+0x4]
0000001A FF7701 push word [bx+0x1]
0000001D E8E0FF call 0x0
00000020 59 pop cx
00000021 5D pop bp
00000022 C3 ret
main:
00000023 56 push si
00000024 BE0E00 mov si,0xe
00000027 56 push si
00000028 E8E9FF call 0x14
0000002B 59 pop cx
0000002C 5E pop si
0000002D C3 ret
datasegment:
0000002E 3132 xor [bp+si],si
00000030 00 db 0x00
printLetter and printString are ok. Call increases sp by a word and
bp is pushed onto stack at the function's beginning. Therefore [bp+0x4]
points to the right content.
If I open out.bin in a text-editor the string "12" is the last two chars
in file. This is similar to the linker's mapping output that locates the
datasegment at 2Eh as described in the disassembler's output above.
The thing I do not understand is what is done at address
00000024 BE0E00 mov si,0xe
00000027 56 push si
This is the value passed to printString as the address of parameter "txt".
What does 0xe mean? It neither can be the offset in the data-segment nor
is it a valid offset on stack. I think that is the reason why the printed
letter does not match the implemented one.
But what do I have to do to fix the bug ?
Can anybody help?
Thanks in advance.
Mathew