gcc 在我的系统上生成什么汇编语言?
What assembly language does gcc produce on my system?
我正在尝试学习一些关于汇编的知识。我决定首先查看从简单源代码生成的汇编文件。当然,我被指令轰炸了,我不知道它们是什么意思,我开始在互联网上搜索它们的含义。在搜索时,我意识到我不知道我在寻找什么汇编语言..
有没有办法知道 gcc 生成的是哪种汇编语言?这个问题甚至有意义吗?
我主要对我的系统接受的程序集感兴趣(或者我应该这样说..)。请参阅下面使用 gcc 生成的代码。
如果你意识到我有哪些知识空白,请link将相关文档转read/study。
系统:
OS: Windows 10 专业版
处理器:英特尔(R) 酷睿(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 , %rsp
.seh_stackalloc 48
.seh_endprologue
call __main
movl , -4(%rbp)
movl [=10=], %eax
addq , %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (Rev10, Built by MSYS2 project) 10.2.0"
GCC 在任何平台上总是生成 GNU assembler 可以 assemble 的 asm 输出。 (GAS / GNU as
是 GNU Binutils 的一部分,还有像 ld
这样的工具,一个链接器。)
在你的情况下,目标是 x86-64 Windows(概率来自 x86_64-w64-mingw32-gcc),
指令语法为AT&T syntax(GCC 和 GAS 默认为 x86,包括 x86-64)。
GAS for x86(包括x86-64)的注释字符为#
。
任何以 .
开头的都是 指令 ;有些,例如 .globl main
将符号 main
导出为在 .o
中可见的链接,通常对 GAS 通用;检查 GAS manual.
像 .seh_setframe %rbp, 0
这样的 SEH 指令是 Windows 特定于 Structured Exception Handling 的堆栈展开元数据,特定于 Windows 目标文件格式。 (你可以 100% 忽略,until/unless 你想了解回溯和异常处理在幕后是如何工作的,而不依赖于一系列遗留的帧指针。据我所知,它基本上等同于 ELF/Linux .eh_frame
来自 .cfi
指令的元数据。)
事实上,您几乎可以忽略所有指令,只有 真正 重要的部分是 .text
vs . .data
,并且对于使链接工作成为 .globl
有点重要。这就是 https://godbolt.org/ 默认过滤指令的原因。
你可以使用gcc -masm=intel
如果你想要英特尔的语法/助记符,你可以在英特尔的手册中查找。 (https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html / https://www.felixcloutier.com/x86/). See also 。(gcc -O1 -fverbose-asm
可能很有趣。)
如果您想学习 AT&T 语法,请参阅 https://whosebug.com/tags/att/info. The GAS manual also has a page about AT&T vs. Intel syntax, but it's not written as a tutorial, i.e. it assumes you know how x86 instructions work, and are looking for details on the syntax GAS uses to describe them: https://sourceware.org/binutils/docs/as/i386_002dVariations.html
(请记住,CPU 实际上运行的是机器码,字节如何进入内存并不重要,重要的是它们进入内存的方式。如此不同的 assemblers(如 NASM vs. GAS)和不同的语法(如.intel_syntax noprefix
)最终对机器在一条指令中能做什么或不能做什么有相同的限制。所有主流的assemblers都可以让你表达相当多每条指令可以做的所有事情,这只是了解立即数、寻址模式等语法的问题。英特尔和 AMD 的手册准确地记录了 CPU 可以做什么,使用英特尔语法但没有确定细节语法或指令。)
资源(包括上面链接的一些):
- Matt Godbolt 的 CppCon2017 演讲“What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid” and
- x86 tag wiki
- https://whosebug.com/tags/att/info
- https://sourceware.org/binutils/docs/as/ 燃气手册
- https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html 英特尔手册
- https://support.amd.com/TechDocs/24594.pdf(AMD 手册第 3 卷:通用指令)
Is there a way to know which assembly language gcc generates?
是的,您的目标端口。这似乎是 x86。这种汇编语言又具有各种风格和方言,有着悠久的历史:https://en.wikipedia.org/wiki/X86_assembly_language
Of course, I get bombarded by instructions that I have no idea what they mean
阅读 C 编译器生成的汇编程序 比阅读手工编码的汇编程序难得多。我建议从一些汇编教程开始,而不是使用人类编写的代码示例。
x86 也可能是其中最难的一个,因为所有的风格,以及核心的复杂性。一般建议先学习一些简单的汇编程序来掌握它。
8 位微控制器是一个很好的起点。
我正在尝试学习一些关于汇编的知识。我决定首先查看从简单源代码生成的汇编文件。当然,我被指令轰炸了,我不知道它们是什么意思,我开始在互联网上搜索它们的含义。在搜索时,我意识到我不知道我在寻找什么汇编语言..
有没有办法知道 gcc 生成的是哪种汇编语言?这个问题甚至有意义吗? 我主要对我的系统接受的程序集感兴趣(或者我应该这样说..)。请参阅下面使用 gcc 生成的代码。
如果你意识到我有哪些知识空白,请link将相关文档转read/study。
系统:
OS: Windows 10 专业版
处理器:英特尔(R) 酷睿(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 , %rsp
.seh_stackalloc 48
.seh_endprologue
call __main
movl , -4(%rbp)
movl [=10=], %eax
addq , %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (Rev10, Built by MSYS2 project) 10.2.0"
GCC 在任何平台上总是生成 GNU assembler 可以 assemble 的 asm 输出。 (GAS / GNU as
是 GNU Binutils 的一部分,还有像 ld
这样的工具,一个链接器。)
在你的情况下,目标是 x86-64 Windows(概率来自 x86_64-w64-mingw32-gcc),
指令语法为AT&T syntax(GCC 和 GAS 默认为 x86,包括 x86-64)。
GAS for x86(包括x86-64)的注释字符为#
。
任何以 .
开头的都是 指令 ;有些,例如 .globl main
将符号 main
导出为在 .o
中可见的链接,通常对 GAS 通用;检查 GAS manual.
像 .seh_setframe %rbp, 0
这样的 SEH 指令是 Windows 特定于 Structured Exception Handling 的堆栈展开元数据,特定于 Windows 目标文件格式。 (你可以 100% 忽略,until/unless 你想了解回溯和异常处理在幕后是如何工作的,而不依赖于一系列遗留的帧指针。据我所知,它基本上等同于 ELF/Linux .eh_frame
来自 .cfi
指令的元数据。)
事实上,您几乎可以忽略所有指令,只有 真正 重要的部分是 .text
vs . .data
,并且对于使链接工作成为 .globl
有点重要。这就是 https://godbolt.org/ 默认过滤指令的原因。
你可以使用gcc -masm=intel
如果你想要英特尔的语法/助记符,你可以在英特尔的手册中查找。 (https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html / https://www.felixcloutier.com/x86/). See also gcc -O1 -fverbose-asm
可能很有趣。)
如果您想学习 AT&T 语法,请参阅 https://whosebug.com/tags/att/info. The GAS manual also has a page about AT&T vs. Intel syntax, but it's not written as a tutorial, i.e. it assumes you know how x86 instructions work, and are looking for details on the syntax GAS uses to describe them: https://sourceware.org/binutils/docs/as/i386_002dVariations.html
(请记住,CPU 实际上运行的是机器码,字节如何进入内存并不重要,重要的是它们进入内存的方式。如此不同的 assemblers(如 NASM vs. GAS)和不同的语法(如.intel_syntax noprefix
)最终对机器在一条指令中能做什么或不能做什么有相同的限制。所有主流的assemblers都可以让你表达相当多每条指令可以做的所有事情,这只是了解立即数、寻址模式等语法的问题。英特尔和 AMD 的手册准确地记录了 CPU 可以做什么,使用英特尔语法但没有确定细节语法或指令。)
资源(包括上面链接的一些):
- Matt Godbolt 的 CppCon2017 演讲“What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid” and
- x86 tag wiki
- https://whosebug.com/tags/att/info
- https://sourceware.org/binutils/docs/as/ 燃气手册
- https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html 英特尔手册
- https://support.amd.com/TechDocs/24594.pdf(AMD 手册第 3 卷:通用指令)
Is there a way to know which assembly language gcc generates?
是的,您的目标端口。这似乎是 x86。这种汇编语言又具有各种风格和方言,有着悠久的历史:https://en.wikipedia.org/wiki/X86_assembly_language
Of course, I get bombarded by instructions that I have no idea what they mean
阅读 C 编译器生成的汇编程序 比阅读手工编码的汇编程序难得多。我建议从一些汇编教程开始,而不是使用人类编写的代码示例。
x86 也可能是其中最难的一个,因为所有的风格,以及核心的复杂性。一般建议先学习一些简单的汇编程序来掌握它。
8 位微控制器是一个很好的起点。