在我找到的所有文档中,没有提到像offset[var+offset2]
Intel x86语法那样的语法,而是带有以下标志的GCC
gcc -S hello.c -o - -masm=intel
对于这个程序
#include<stdio.h>
int main(){
char c = 'h';
putchar(c);
return 0;
}
产生
.file "hello.c"
.intel_syntax noprefix
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
push rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp
.cfi_def_cfa_register 6
sub rsp, 16
mov BYTE PTR -1[rbp], 104
movsx eax, BYTE PTR -1[rbp]
mov edi, eax
call putchar@PLT
mov eax, 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Arch Linux 9.3.0-1) 9.3.0"
.section .note.GNU-stack,"",@progbits
我想突出显示mov BYTE PTR -1[rbp], 104
偏移量-1
出现在方括号之外的那一行。TBH,我只是在猜测这是一个偏移量,有人可以引导我找到突出显示此内容的适当文档吗?
这是一个类似的问题:来自IDA的x86 asm中的方括号,其中的确提到了偏移量,但我确实希望有适当的文档参考。
是的,这只是另一种书写方式[rbp - 1]
,并且-1
是x86技术寻址模式术语1的替代。
GAS手册中有关x86寻址模式的部分仅提到了[ebp - 4]
可能性,没有提到-4[ebp]
,但是GAS确实进行了组装。
以AT&T或Intel语法进行的反汇编可以确认其含义。x86寻址模式受机器可以编码的内容的约束(引用内存位置的内容。(x86寻址模式)),因此对于某些语法的含义没有太多的回旋余地。(此语法是由GCC发出的,因此我们可以放心地假设它是有效的。它的含义与-1(%rbp)
在AT&T语法模式下发出的含义相同。)
脚注1:整个rbp-1
有效地址是seg:off地址的偏移量部分。除FS和GS外,段基础在64位模式下固定为0,即使在32位模式下,主流OS也使用平面内存模型,因此您可以忽略段基础。我指出这一点仅仅是因为x86术语中的“偏移”确实具有与“位移”分开的特定技术含义,以防您关心使用与英特尔手册相匹配的术语。
由于某些原因,GCC的语法选择取决于-fno-pie
或不取决于语法。 https://godbolt.org/z/iK9jh6(在诸如Arch系统之类的现代GNU / Linux发行版上-fpie
,默认情况下处于启用状态,而在Godbolt上则未启用)。
如果volatile
用于强制写入堆栈变量或使用指针执行其他操作,则此选择将继续启用优化功能:例如https://godbolt.org/z/4P92Fk。它适用于ptr[1 + x]
从函数args进行的任意取消引用。
-fno-pie
选择[rbp - 1]
并[rdi+4+rsi*4]
-fpie
选择-1[rbp]
并4[rdi+rsi*4]
IDK为什么GCC的内部构造基于PIE模式选择不同。没有明显的原因;也许由于某些原因,他们只是在GCC内部使用了不同的代码路径,或者是不同的格式字符串,并且它们恰好做出了不同的选择。
无论有无PIE,都将全局(静态存储)称为glob[rip]
,也不[RIP + glob]
支持。在两种情况下,这都意味着glob
相对于RIP,实际上不是RIP +符号的绝对地址。但这是适用于任何其他寄存器或没有寄存器的规则的例外。
GAS.intel_syntax
类似于MASM,并且MASM当然也支持symbol[register]
,我什至认为1234[register]
。排量比较正常。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句