4

NASMによって生成されたリストファイルを見ると、3種類のオペコードがあることがわかります。

  1. 括弧なし。
  2. 丸括弧付き。
  3. 角括弧付き。

それらはどういう意味ですか?それらのそれぞれが使用されるとき?

これは、上記のすべてを示すリストファイルの例です。

 1                                  section .text
 2                                      extern printf
 3                                      extern fgets
 4 00000000 313233                  str3:   db "123"
 5                                  main:
 6 00000003 68[00000000]                push    str1
 7 00000008 68[09000000]                push    str2
 8 0000000D 68[00000000]                push    str3
 9 00000012 E8(00000000)                call    func1
10 00000017 E8(04000000)                call    func2
11 0000001C E80B000000                  call    func3
12 00000021 E8(00000000)                call    printf
13 00000026 E8(00000000)                call    fgets
14 0000002B C3                          ret
15                                  
16 0000002C 90                      func3:  nop
17 0000002D C3                          ret
18                                  
19                                  
20                                  section .text1
21 00000000 90                      func1:  nop
22 00000001 90                          nop
23 00000002 90                          nop
24 00000003 C3                          ret
25                                  
26 00000004 90                      func2:  nop
27 00000005 90                          nop
28 00000006 90                          nop
29 00000007 C3                          ret
30                                  
31                                  
32                                  section .data
33                                  
34 00000000 313233343536373839      str1:   db "123456789"
35 00000009 313233343536373839      str2:   db "123456789"
4

2 に答える 2

10

リンク時に再配置が適用される場所を示しています。

[nnnnnnnn]絶対再配置を示します (リンカが再配置を実行すると、一部のセクションのベース アドレスがオフセットに追加されます)。たとえば、バイナリが完全にリンクされると、命令内のこれらのバイトは+push str2のベースアドレスを含むように変更されます。.data0x09

(nnnnnnnn)PC 相対再配置を示します (呼び出しと分岐に使用され、最終値は次の命令のアドレスに関連している必要があります)。たとえば、命令内のバイトは、の最終アドレスと次の命令 ( ) のアドレスcall func2の差で更新されます。func2call func3

call func3その場合、再配置は必要ないため、命令自体には括弧はありません。call命令には相対アドレスが必要func3ですが、同じセクション内にあるため、相対アドレスは既にわかっています (次の命令は at.text + 0x21であり、func3at.text + 0x2cであるため、相対アドレスは0xbの最終アドレスに関係ありませ.textん)。

于 2012-06-30T16:12:12.650 に答える
4

括弧と角かっこは、それらの内部の命令バイトの部分が参照されるオブジェクトの場所に依存することを意味しますが、これはまだ完全にはわかっていません (OS のリンカやプログラム ローダーによって設定または変更される可能性があります)。

ここでは、関数のアドレスはこのファイルで定義されていないため不明です。そのため、括弧内はすべてゼロになっています。

12 00000021 E8(00000000)                call    printf
13 00000026 E8(00000000)                call    fgets

ここで、 のアドレスに対する のfunc3相対アドレスcall func3は既知 (距離は 2Ch-21h=0Bh) であり、変更されることはないため、括弧や角かっこなしで固定されています。

11 0000001C E80B000000                  call    func3
12 00000021 ...
...
16 0000002C 90                      func3:  nop

ここで、 のアドレスはstr2、セクション間の距離に依存するため、リンク時に変更される可能性があるため、アセンブリ時に部分的に認識されます。したがって、ブラケットがあります。

 7 00000008 68[09000000]                push    str2

かっこと角かっこの違いはわかりません。おそらくコードとデータの違いでしょう。NASM のドキュメントは、おそらく確認するのに適した場所です。そこに記載されていない場合は、利用可能な NASM ソース コードがあり、さらに「テスト」を行うこともできます。

于 2012-06-30T16:17:30.237 に答える