gcc 在我的系统上生成什么汇编语言?

Jus*_*oob 4 c assembly x86-64 instruction-set att

我正在尝试学习一些关于组装的知识。我决定从简单的源代码中查看生成的程序集文件开始。当然,我被指令轰炸,我不知道它们的意思,我开始在互联网上搜索它们的含义。在搜索时,我意识到我不知道我在寻找什么汇编语言..

有没有办法知道 gcc 生成哪种汇编语言?这个问题还有意义吗?我主要对我的系统接受的程序集感兴趣(或者我应该说......)。下面是使用 gcc 生成的代码。

如果你意识到我有哪些知识空白,请链接相关文档阅读/学习。

系统:

操作系统:Windows 10 专业版

处理器:Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz 2.20 GHz

类型:64 位操作系统,基于 x64 的处理器

//test.c

int main(){

    int x = 2;

    return 0;
}

 //test.s
.file   "test.c"
    .text
    .def    __main; .scl    2;  .type   32; .endef
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    pushq   %rbp
    .seh_pushreg    %rbp
    movq    %rsp, %rbp
    .seh_setframe   %rbp, 0
    subq    $48, %rsp
   .seh_stackalloc  48
   .seh_endprologue
    call    __main
    movl    $2, -4(%rbp)
    movl    $0, %eax
    addq    $48, %rsp
    popq    %rbp
    ret
   .seh_endproc
   .ident   "GCC: (Rev10, Built by MSYS2 project) 10.2.0"
Run Code Online (Sandbox Code Playgroud)

Pet*_*des 7

GCC 总是产生GNU 汇编器可以在任何平台上汇编的asm 输出。(GAS / GNUas是 GNU Binutils 的一部分,还有诸如ld链接器之类的工具。)

在你的情况下,目标是X86-64的Windows(概率。从x86_64的-W64-的mingw32-GCC),
指令语法是AT&T的语法(GCC和GAS默认为86,包括x86-64的)。

注释字符#在 x86(包括 x86-64)的 GAS 中。
任何以 a 开头的.都是一个指令;有些人喜欢.globl main导出链接中main可见的符号.o,通常对 GAS 是通用的;检查气体手册

SEH 指令类似于.seh_setframe %rbp, 0Windows 特定的用于结构化异常处理的堆栈展开元数据,特定于 Windows 对象文件格式。(您可以 100% 忽略,直到/除非您想了解回溯和异常处理如何在幕后工作,而不依赖于传统的帧指针链。AFAIK,它基本上等同.eh_frame.cfi指令中的ELF/Linux元数据。)

事实上,您几乎可以忽略所有指令,唯一真正重要的是像.textvs.这样的部分.data,并且对于使链接工作有些重要.globl。这就是https://godbolt.org/默认过滤指令的原因。


gcc -masm=intel如果您想要 Intel 语法/助记符,您可以使用它,您可以在 Intel 的手册中查找。(https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html / https://www.felixcloutier.com/x86/)。另请参阅如何从 GCC/clang 程序集输出中去除“噪音”?. (gcc -O1 -fverbose-asm可能很有趣。)

如果您想学习 AT&T 语法,请参阅https://stackoverflow.com/tags/att/info。GAS 手册还有一个关于 AT&T 与 Intel 语法的页面,但它不是作为教程编写的,即它假设您知道 x86 指令的工作原理,并且正在寻找 GAS 用来描述它们的语法的详细信息: https:// sourceware.org/binutils/docs/as/i386_002dVariations.html

(请记住,CPU 实际上运行机器代码,并且字节如何进入内存并不重要,只是它们确实如此。因此不同的汇编程序(如 NASM 与 GAS)和不同的语法(如.intel_syntax noprefix)最终具有相同的机器在一条指令中可以做什么或不可以做什么的限制。所有主流汇编程序都可以让您表达每条指令可以做的几乎所有事情,只需了解立即数、寻址模式等的语法。Intel 和 AMD 的手册使用 Intel 语法准确记录 CPU 可以做什么,但不明确语法或指令的细节。)


资源(包括上面链接的一些):

  • 在 [x86 tag wiki](https://stackoverflow.com/tags/x86/info) 下也可以找到大量资源,这主要归功于我们常驻的 x86 大师 @Peter Cordes :) (3认同)
  • @old_timer:指令使用 AT&T 语法,指令是 GAS 指令。我认为说“不是 AT&T”对任何人都没有任何好处。您是否想指出我应该在关于 GAS 的段落中更多地讨论指令,而不是在关于 AT&T 语法的段落中更多地讨论指令,这是 GAS 对于 x86 目标的默认设置?请注意,某些指令*是*特定于目标的(目标文件格式),例如“.seh_*” (3认同)