在x86 intel asm的GCC上,方括号前的偏移。

问题描述 投票:3回答:1

在我找到的所有文档中,都没有提到像这样的语法 offset[var+offset2] 在英特尔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,我只是猜测它是一个偏移,谁能指导我找到一个适当的文档来强调这一点?

下面是一个类似的问题。"方括号在x86 asm中的应用",来自IDA 其中有一条评论提到它是一个偏移量,但我真的很想得到一个合适的文档参考。

gcc assembly x86 gas intel-syntax
1个回答
5
投票

是的,这只是另一种写法。[rbp - 1]-1 是一个 流离失所 在x86技术寻址模式术语中1.

GAS手册的章节 关于x86寻址模式 只说 [ebp - 4] 可能性,而不是 -4[ebp],但GAS是会组装的。

而用AT&T或英特尔的语法进行反汇编,则证实了它的意思。x86的寻址模式受到机器能编码的限制(引用一个内存位置的内容。(x86寻址模式)),所以在一些语法的含义上没有太多回旋余地。 (这个语法是由GCC发出的,所以我们可以放心地认为它是有效的。. 而且它的意思是相同的事情,因为 -1(%rbp) 它在AT&T语法模式下发出的)。)

脚注1:整个 rbp-1 有效地址为 偏移 seg:off地址的一部分。 在64位模式下,除了FS和GS之外,段基是固定为0的,即使在32位模式下,主流的操作系统也是采用扁平化的内存模型,所以你可以忽略段基。 我之所以指出这一点,只是因为x86术语中的 "offset "确实有与 "displacement "分开的特定技术含义,万一你在意使用的术语与Intel的手册相符呢?


由于某些原因,GCC对语法的选择取决于 -fno-pie 或不。 https:/godbolt.orgziK9jh6 (在现代GNULinux发行版上,比如你的Arch系统。-fpie 默认启用. 在Godbolt上不是)。)

启用优化后,如果你使用 volatile 强制写入堆栈变量,或者用指针做其他事情:比如说。https:/godbolt.orgz4P92Fk。. 它适用于任意的贬义,如 ptr[1 + x] 从函数args。

  • GCC -fno-pie 选择 [rbp - 1][rdi+4+rsi*4]
  • 海湾合作委员会 -fpie 选择 -1[rbp]4[rdi+rsi*4]

IDK为什么GCC的内部程序会根据PIE模式做出不同的选择。 没有明显的原因,也许是出于某种原因,他们只是在GCC的内部使用了不同的代码路径,或者是不同的格式字符串,他们只是碰巧做出了不同的选择。

无论是有PIE还是没有PIE,一个全局(静态存储)都会被引用为 glob[rip],不 [RIP + glob] 这也是支持的。 在这两种情况下,这意味着 glob 关于 RIP,其实不是RIP+符号的绝对地址。 但这是一个例外,适用于任何其他寄存器,或者没有寄存器的规则。


GAS .intel_syntax 是类似于MASM的,MASM当然也支持 symbol[register] 甚至我认为 1234[register]. 这是更正常的位移。

© www.soinside.com 2019 - 2024. All rights reserved.