Wil*_*ver 6 macos assembly stack gcc x86-64
我刚刚开始使用GCC编译器来学习汇编我的代码.不幸的是,如果你是初学者,有非常有限的资源来学习如何做到这一点.我终于设法找到了一些简单的示例代码,我可以开始说清楚了,我得到它来组装并正确运行.这是代码:
.text # start of code indicator.
.globl _main # make the main function visible to the outside.
_main: # actually label this spot as the start of our main function.
push %rbp # save the base pointer to the stack.
mov %rsp, %rbp # put the previous stack pointer into the base pointer.
subl $8, %esp # Balance the stack onto a 16-byte boundary.
movl $0, %eax # Stuff 0 into EAX, which is where result values go.
leave # leave cleans up base and stack pointers again.
ret
Run Code Online (Sandbox Code Playgroud)
这些评论解释了代码中的一些内容(我有点理解第2 - 5行的内容),但我不明白大多数这意味着什么.我明白了什么寄存器是基础知识,每个寄存器的这里(rbp,rsp,esp和eax)用于和有多大他们,我也理解(通常情况下)堆栈是什么,但是这仍然会在我的头上.谁能告诉我到底这是做什么的?还有,有人能指出我为初学者提供一个好的教程吗?
nrz*_*nrz 12
堆栈是遵循LIFO原则的数据结构.虽然日常生活中的堆栈(我的意思是计算机外)向上增长,但x86和x86-64处理器中的堆栈却向下增长.请参阅x86堆栈上的Wikibooks文章(但请注意,代码示例是Intel语法中的32位x86代码,并且您的代码是AT&T语法中的64位x86-64代码).
那么,你的代码做了什么(我的解释是英特尔语法):
push %rbp
Run Code Online (Sandbox Code Playgroud)
推rbp送到堆栈,实际上减去8 rsp(因为大小rbp是8字节),然后存储rbp到[ss:rsp].
因此,在Intel语法中push rbp实际上这样做:
sub rsp, 8
mov [ss:rsp], rbp
Run Code Online (Sandbox Code Playgroud)
然后:
mov %rsp, %rbp
Run Code Online (Sandbox Code Playgroud)
这很明显.只需将值rsp存入rbp.
subl $8, %esp
Run Code Online (Sandbox Code Playgroud)
从中减去8 esp并将其存储到esp.实际上这是你的代码中的一个错误,即使它在这里没有引起任何问题.用一个32位的寄存器的任何指令(eax,ebx,ecx,edx,ebp,esp,esi或edi作为目的地)中的x86-64设置相应的64位寄存器的最上面32位(rax,rbx,rcx,rdx,rbp,rsp,rsi或rdi)到零,从而使堆指向低于4 GiB限制的指针,有效地执行此操作(在Intel语法中):
sub rsp,8
and rsp,0x00000000ffffffff
Run Code Online (Sandbox Code Playgroud)
编辑:增加sub esp,8下面的后果.
但是,这会导致内存小于4 GiB的计算机出现问题.在具有4个以上GiB内存的计算机上,可能会导致分段错误.leave在下面的代码中返回一个合理的值rsp.通常在x86-64代码中,您不需要esp(不包括可能的一些优化或调整).要修复此错误:
subq $8, %rsp
Run Code Online (Sandbox Code Playgroud)
到目前为止的指令是标准的入口序列($8根据堆栈使用情况进行替换).Wikibooks有一篇关于x86函数和堆栈框架的有用文章(但请注意,它使用的是32位x86程序集,采用Intel语法,而不是采用AT&T语法的64位x86-64程序集).
然后:
movl $0, %eax
Run Code Online (Sandbox Code Playgroud)
这很明显.将0存入eax.这与堆栈无关.
leave
Run Code Online (Sandbox Code Playgroud)
这相当于mov rsp, rbp后面跟着pop rbp.
ret
Run Code Online (Sandbox Code Playgroud)
最后,这将设置rip为存储的值[ss:rsp],有效地将代码指针返回到调用此过程的位置,并添加8 rsp.
| 归档时间: |
|
| 查看次数: |
4333 次 |
| 最近记录: |