動作しない原因をビルド時の中間ファイルを見ながら調査しました
1.まずはTEST.Cのコンパイル結果です。
単に文字列のアドレスをスタックに積んで文字列出力関数putstr()に渡すだけです
単に文字列のアドレスをスタックに積んで文字列出力関数putstr()に渡すだけです
.file "test.c" gcc2_compiled.: ___gnu_compiled_c: .text LC0: .ascii "Hello, C world.\12\15\0" .p2align 2 .globl _main _main: pushl %ebp movl %esp,%ebp .align 2,0x90 L4: pushl $LC0 call _putstr addl $4,%esp jmp L4 .align 2,0x90
2.次にリンク時のメモリマップです。
指定どおりコードが0x2000、データが0x10000から割り付けられています
またmain関数のロケーションは0x201cであることがわかります
指定どおりコードが0x2000、データが0x10000から割り付けられています
またmain関数のロケーションは0x201cであることがわかります
Linker script and memory map Address of section .text set to 0x2000 Address of section .bss set to 0x10000 LOAD start.o LOAD test.o LOAD 386lib.o LOAD c:\usr\asm\djgpp\lib/libc.a .text 0x00002000 0x800 *(.text) .text 0x00002000 0x8 start.o 0x00002000 start .text 0x00002008 0x28 test.o 0x0000201c main .text 0x00002030 0x5f4 386lib.o 0x00002230 _matherr 0x00002518 lcdini 0x00002130 cnv_tbl_in 0x00002498 getstr 0x0000253c lcdctr 0x000024d0 lcdcset 0x00002564 lcdstr 0x000023b0 sioled 0x00002474 putstr 0x000023f8 wait : :
-u2000 _start: 0000:2000 E81700 CALL 201A 0000:2003 0000 ADD [BX+SI],AL 0000:2005 F4 HLT _end: _main: 0000:201C 55 PUSH BP 0000:201D 89E5 MOV BP,SP 0000:201F 90 NOP L4: 0000:2020 680820 PUSH 2008 0000:2023 0000 ADD [BX+SI],AL 0000:2025 E84A04 CALL 2472 0000:2028 0000 ADD [BX+SI],AL 0000:202A 83C404 ADD SP,+04 0000:202D EBF1 JMP 2020 0000:202F 90 NOP
この逆アセンブルリストをじーっと見ているとおかしい点に気づきました
①コール先アドレスが違う
main関数は0x201c番地、putstr関数0x2474番地にリロケートされているのに
それぞれ呼んでいるほうは CALL 201A, CALL 2472 と2番地手前
main関数は0x201c番地、putstr関数0x2474番地にリロケートされているのに
それぞれ呼んでいるほうは CALL 201A, CALL 2472 と2番地手前
②CALL命令の後に「00」が2バイト挿入されている
結果的にこれが「ADD [BX+SI],AL」という意味不明なコードが挿入されたことになっている
結果的にこれが「ADD [BX+SI],AL」という意味不明なコードが挿入されたことになっている