組み込みプログラムの生成に gcc を使用しようとしています。gcc は、Windows で通常のアプリケーションを生成するために使用するのと同じ gcc である Mingw ツールセットに由来します。組み込み i386/32 ビット システムで使用するために、0x1000 にあるストレート バイナリを生成しようとしています。Bochs の下でテストされます。
私のリンカーファイルは次のようになります。
/* a list of files to link */
INPUT(test.o)
/* output format */
OUTPUT_FORMAT("pe-i386")
/* output filename */
/* OUTPUT_FILENAME("test.out") */
/* list of our memory sections */
MEMORY
{
ram : o = 0x1000, l = 256k
}
/* place sections */
SECTIONS
{
/* code and constants */
.text :
{
__text_start = .;
*(.text)
*(.strings)
__text_end = .;
} > ram
/* initialized data */
.data :
{
__data_start = .;
*(.data)
__data_end = .;
} > ram
/* uninitialized data */
.bss :
{
__bss_start = . ;
*(.bss)
*(COMMON)
__bss_end = . ;
} > ram
}
基本的に、RAM の 0x1000 のターゲット アドレスにすべてを連結することを意味します。
PE ファイル以外のターゲットを選択すると、次のようになります。
非 PE ファイルに対して PE 操作を実行できません...
ここにあるその他のメッセージは、Windows 上の ld に関する既知の問題です。そこで、objcopy を使用してバイナリを作成する別の手順を実行しましたが、これは正常に機能します。
出力セクションは次のとおりです。
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000038 ffc01000 ffc01000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rdata 00000010 ffc02000 ffc02000 00002000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .eh_frame 00000038 ffc03000 ffc03000 00003000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
したがって、セクションは、私が気に入っているページ フレーム アドレス (4kb) に配置されています。.text フレームの分解は次のとおりです。
test.pe: file format pe-i386
Disassembly of section .text:
ffc01000 <_crap>:
ffc01000: 55 push ebp
ffc01001: 89 e5 mov ebp,esp
ffc01003: 83 ec 10 sub esp,0x10
ffc01006: c7 45 f8 00 20 00 00 mov DWORD PTR [ebp-0x8],0x2000
ffc0100d: c7 45 fc 00 80 0b 00 mov DWORD PTR [ebp-0x4],0xb8000
ffc01014: eb 14 jmp ffc0102a <_crap+0x2a>
ffc01016: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8]
ffc01019: 8a 00 mov al,BYTE PTR [eax]
ffc0101b: 66 98 cbw
ffc0101d: 8b 55 fc mov edx,DWORD PTR [ebp-0x4]
ffc01020: 66 89 02 mov WORD PTR [edx],ax
ffc01023: 83 45 fc 02 add DWORD PTR [ebp-0x4],0x2
ffc01027: ff 45 f8 inc DWORD PTR [ebp-0x8]
ffc0102a: 83 7d f8 00 cmp DWORD PTR [ebp-0x8],0x0
ffc0102e: 75 e6 jne ffc01016 <_crap+0x16>
ffc01030: b8 00 00 00 00 mov eax,0x0
ffc01035: c9 leave
ffc01036: c3 ret
ffc01037: 90 nop
そのため、コードが 0xffc01000 に配置された方法や理由がわかりません。これは、リンカ命令ファイルで指定したものではありません。
これは PE ファイル形式のアーティファクトであるという考えで、elf のような他の出力形式を選択しようとしましたが、そうすると、「非 PE 出力ファイルで PE 操作を実行できません」というバグにぶつかりました。
質問は次のとおりです。
- 0xffc01000 に配置されるのはなぜですか? これは、Windows プログラムのコンテキストでも意味がないように見えます。
- プログラムを正しく見つける方法はありますか?
- Windows に関連付けられていない i386 gcc ビルドを使用する必要がありますか?
ありがとうございました、
スコット・ムーア