简单C++程序的程序集输出
assembly output of a simple C++ program
我正在尝试理解一个简单的c ++程序的汇编输出。这是我C++程序。
void func()
{}
int main()
{
func();
}
当我使用 g++ 和 --save-temps 选项来获取上述程序的汇编代码时,我得到以下汇编代码。
.file "main.cpp"
.text
.globl _Z4funcv
.type _Z4funcv, @function
_Z4funcv:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size _Z4funcv, .-_Z4funcv
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
call _Z4funcv
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
根据我对汇编的了解,任何汇编程序都应该有 3 个部分,即数据、文本和 bss。此外,文本部分应以"全局_start"开头。我在此汇编代码中看不到它们中的任何一个。有人可以帮我理解上面的汇编代码吗?如果您也可以与C++代码相关联,那就太好了。
非常感谢任何形式的帮助。
好吧,这是一行一行...
.file "main.cpp" # Debugging info (not essential)
.text # Start of text section (i.e. your code)
.globl _Z4funcv # Let the function _Z4funcv be callable
# from outside (e.g. from your main routine)
.type _Z4funcv, @function # Debugging info (possibly not essential)
_Z4funcv: # _Z4funcv is effectively the "name" of your
# function (C++ "mangles" the name; exactly
# how depends on your compiler -- Google "C++
# name mangling" for more).
.LFB0: # Debugging info (possibly not essential)
.cfi_startproc # Provides additional debug info (ditto)
pushq %rbp # Store base pointer of caller function
# (standard function prologue -- Google
# "calling convention" or "cdecl")
.cfi_def_cfa_offset 16 # Provides additional debug info (ditto)
.cfi_offset 6, -16 # Provides additional debug info (ditto)
movq %rsp, %rbp # Reset base pointer to a sensible place
# for this function to put its local
# variables (if any). Standard function
# prologue.
.cfi_def_cfa_register 6 # Debug ...
popq %rbp # Restore the caller's base pointer
# Standard function epilogue
.cfi_def_cfa 7, 8 # Debug...
ret # Return from function
.cfi_endproc # Debug...
.LFE0: # Debug...
.size _Z4funcv, .-_Z4funcv # Debug...
.globl main # Declares that the main function
# is callable from outside
.type main, @function # Debug...
main: # Your main routine (name not mangled)
.LFB1: # Debug...
.cfi_startproc # Debug...
pushq %rbp # Store caller's base pointer
# (standard prologue)
.cfi_def_cfa_offset 16 # Debug...
.cfi_offset 6, -16 # Debug...
movq %rsp, %rbp # Reset base pointer
# (standard prologue)
.cfi_def_cfa_register 6 # Debug...
call _Z4funcv # Call `func` (note name mangled)
movl $0, %eax # Put `0` in eax (eax is return value)
popq %rbp # Restore caller's base pointer
# (standard epilogue)
.cfi_def_cfa 7, 8 # Debug...
ret # Return from main function
.cfi_endproc # Debug...
.LFE1:
.size main, .-main # Debug...
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2" # fluff
.section .note.GNU-stack,"",@progbits # fluff
链接器知道查找main
(而不是start
),如果它使用的是标准的 C 或 C++ 库(通常是这样,除非你另有说明)。 它将一些存根代码(包含start
)链接到最终的可执行文件中。
所以,真的,唯一重要的部分是...
.text
.globl _Z4funcv
_Z4funcv:
pushq %rbp
movq %rsp, %rbp
popq %rbp
ret
.globl main
main:
pushq %rbp
movq %rsp, %rbp
call _Z4funcv
movl $0, %eax
popq %rbp
ret
如果你想从头开始,而不是让所有复杂的标准库的东西妨碍你的发现,你可以做这样的事情,并达到与你的C++代码相同的结果:
.text
.globl _func
_func: # Just as above, really
push %ebp
mov %esp, %ebp
pop %ebp
ret
.globl _start
_start: # A few changes here
push %ebp
mov %esp, %ebp
call _func
movl $1, %eax # Invoke the Linux 'exit' syscall
movl $0, %ebx # With a return value of 0 (pick any char!)
int $0x80 # Actual invocation
退出系统调用有点痛苦,但很有必要。 如果你没有它,它会尝试继续运行"过去"你的代码。 由于这可能是重要的代码或数据,因此计算机应因分段错误而停止您。 退出呼叫可以避免这一切。 如果您使用的是标准库(在您的C++示例中会自动发生),则退出内容由链接器处理。
使用gcc -nostdlib -o test test.s
编译(注意 gcc 被明确告知不要使用标准库)。 我应该说这是针对 32 位系统的,很可能不适用于 64 位。 我没有 64 位系统可以测试,但也许一些有用的 StackOverflower 会加入 64 位翻译。
相关文章:
- 内联程序集printf将整数解释为地址
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 具有外部"c"和程序集的未定义函数
- 用于将C++代码转换为 Web 程序集的脚本未终止
- 为什么我的C++程序的程序集输出充满了 .ascii,没有汇编代码?
- 为什么这个程序的输出不如预期
- CoreCLR 中的检测探查器 - 将帮助程序程序集加载到 dotnet 进程的方法
- 如何在 html 页面中插入 cgi 应用程序的输出?
- 不同于按值传递和常量引用传递的程序集
- 为什么在堆栈和堆上创建变量会产生相同的程序集代码?
- C++变量在调用 x64 程序集函数后重置为 0
- 不明白这个程序的输出
- 如何将C++子例程链接到 x86 程序集程序?
- 是否可以在C++中基于程序集输出(.dll或.exe)定义变量
- ARM Cortex-A8:使用简单浮点乘法时,来自交叉编译器的不同程序集输出
- G++ 转储的程序集输出不起作用
- 简单C++程序的程序集输出
- 我是否正确解释了Visual Studio程序集输出
- c++从程序集输出的角度理解虚析构函数如何增加类型的大小
- 编译输出程序集