Hri*_*tik 3 x86 assembly gcc gnu-assembler intel-syntax
从我发现的所有文档中,没有提到像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;
}
Run Code Online (Sandbox Code Playgroud)
产生
.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
Run Code Online (Sandbox Code Playgroud)
我想突出显示mov BYTE PTR -1[rbp], 104偏移-1出现在方括号外的行。TBH,我只是猜测这是一个偏移量,任何人都可以指导我找到突出显示这一点的适当文档吗?
这是一个类似的问题:来自 IDA 的 x86 asm 中的 Squared Brackets评论确实提到它是一个偏移量,但我真的很想要一个适当的文档参考。
是的,这只是另一种写法[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 地址的偏移部分。64 位模式下段基数固定为 0,除了 FS 和 GS,即使在 32 位模式下主流操作系统也使用平面内存模型,因此可以忽略段基数。我指出这一点只是因为 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]. 位移比较正常。
| 归档时间: |
|
| 查看次数: |
243 次 |
| 最近记录: |