4

查看由 NASM 生成的列表文件时,我看到有三种操作码:

  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指令中的那些字节将被更改为包含.data+的基地址0x09

(nnnnnnnn)显示 PC 相对重定位(用于调用和分支,其中最终值必须相对于下一条指令的地址)。例如,指令中的字节将使用 的最终地址和下一条指令 ( )的地址call func2之间的差异进行更新。func2call func3

指令本身没有括号,call func3因为在这种情况下不需要重定位 -call指令需要一个相对地址,但func3在同一段内,所以相对地址是已知的(下面的指令是 at .text + 0x21,并且func3是 at .text + 0x2c,所以相对地址0xb与 ) 的最终地址无关.text

于 2012-06-30T16:12:12.650 回答
4

括号和方括号表示其中的指令字节部分取决于引用对象的位置,该位置尚不完全清楚(可能由操作系统中的链接器和/或程序加载器设置或更改)。

在这里,函数的地址是未知的,因为它们没有在这个文件中定义,所以括号中的全是零:

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 回答