Sin*_*ock 5 x86 assembly gnu-assembler
我将准确列出我不理解的内容,并向您展示我无法理解的部分.
首先,
.Align指令
1.~?:隐含的" 导致生成的下一个数据以模整数字节对齐?" 我猜想下一个生成的数据是内存到寄存器的传输,不是吗?Modulo意味着分裂的其余部分.我不明白" 要对齐模数整数字节 ".......
什么是简单数据声明的剩余部分,以及由余数对齐生成的下一个数据如何有用?如果下一个数据以模数对齐,那就说下一个生成的数据,无论这意味着什么,是整数的余数?这绝对没有意义.
具体而言,.align 8在x86中为从C编译的数据字节发出的.align 指令是什么char,即char CHARACTER = 0;用于?或者直接用该指令编码,而不是编译C后的初步汇编代码?我已经在调试大会和发现任何C/C++数据声明,如chars,ints,floats,等会插入指令,.align 8他们每个人,并添加其他指令一样.bss,.zero,.globl,.text,.Letext0,.Ltext0.
所有这些指令是什么,或者至少是我的主要要求?我已经学习了很多主要的x86汇编指令,但从未被引入或指向所有这些奇怪的指令.它们如何影响操作码,并且都是必要的?
首先,请注意.align它不是特定于 x86 的概念,而是此处记录的 GNU GAS 指令。它也可以用于其他架构。x86 不指定指令,只指定指令。
现在让我们玩弄它来理解它:
作为
.byte 1
.align 16
sym: .byte 2
Run Code Online (Sandbox Code Playgroud)
编译和反编译:
as -o a.o a.S
objdump -Sd a.o
Run Code Online (Sandbox Code Playgroud)
输出:
0000000000000000 <a-0x10>:
0: 01 0f add %ecx,(%rdi)
2: 1f (bad)
3: 44 00 00 add %r8b,(%rax)
6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
d: 00 00 00
0000000000000010 <sym>:
10: 02 .byte 0x2
Run Code Online (Sandbox Code Playgroud)
所以sym被移到第.byte 116 个字节,即我们放置的第一个之后的第一个 16 的倍数,以使其与 16 个字节对齐。
用于填充的字节01和02由 GAS 选择的垃圾(TODO 如何?)
不要让我们尝试不同的输入:
.skip 5
.align 4
sym: .byte 2
Run Code Online (Sandbox Code Playgroud)
给出:
0000000000000000 <sym-0x8>:
0: 00 00 add %al,(%rax)
2: 00 00 add %al,(%rax)
4: 00 0f add %cl,(%rdi)
6: 1f (bad)
...
0000000000000008 <sym>:
8: 02 .byte 0x2
Run Code Online (Sandbox Code Playgroud)
所以这一次sym被转移到8,这是第一多个4自带之后5。
正如评论中所提到的,这意味着编译器将添加足够的填充字节,以便下一个数据落在"偶数"位置(可被对齐值整除).这很重要,因为对齐的内存访问比未对齐的内存访问快得多.(从0x10000加载双字比从0x10001加载双字更好).如果您与其他组件连接并且需要使用给定的填充/对齐发送/接收数据结构,它也可能很有用.