2

組み込みプログラムの生成に 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 操作を実行できません」というバグにぶつかりました。

質問は次のとおりです。

  1. 0xffc01000 に配置されるのはなぜですか? これは、Windows プログラムのコンテキストでも意味がないように見えます。
  2. プログラムを正しく見つける方法はありますか?
  3. Windows に関連付けられていない i386 gcc ビルドを使用する必要がありますか?

ありがとうございました、

スコット・ムーア

4

0 に答える 0