大佬教程收集整理的这篇文章主要介绍了了解汇编、nasm、x86 中的 printf 函数。我不知道为什么这段代码没有打印出任何东西,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
BITS 64;
global main
extern printf
section .text
main: ; This is called by the C library startup code
push rbx ; required to make printf 16-byte aligned.
; For Now we only do this once!
push qword 300
call sum
mov rdi,dfmt ; set 1st parameter (format)
mov rsi,rax ; set 2nd parameter (low bytE)
xor rax,rax ; because printf is varargs we must clear rax
call printf ; printf(format,current_number)
pop rbx ; must restore rbx for linux
ret ; Return from main BACk into C library wrapper
sum:
push rbp ; retrIEve parameter
push rbx ; save prevIoUs
mov rbp,rsp
add rsp,24 ; create room for Integer
mov rbx,[rbp] ; rbx = param
cmp rbx,0 ; if (n <= 0)
je base
dec rbx ; decrement rbx to place in stack
push rbx ; put (rbx - 1) in stack
inc rbx
call sum ; calculate sum(n - 1)
add rax,rbx
pop rbx
jmp end
base:
mov rax,1
end:
pop rbx
pop rbp
ret
dfmt:
db "%ld",10,0
让我们一点一点地经历这个。
在 @H_577_3@main 函数中,您有 push qword 300
。我认为这是为了将参数传递给 sum
?如果是这样......那不是你在做什么。我建议改为遵循 AMD64 调用约定并使用 @H_577_3@mov rdi,300 然后使用 call sum
,这会期望在 rdi
中找到它的第一个参数。
无论如何,在 sum
中,您要做的第一件事是 push rbp
,这是非常标准的。那么你push rbx
。这是一个被调用者保存的寄存器,很好。然后是 @H_577_3@mov rbp,rsp,这也是非常标准的。
现在你释放一些带有add rsp,24
的堆栈,我不明白。堆栈向低地址增长,因此要保留一些堆栈,您可以从 rsp
中减去。但也许这不是你在做什么?
现在我真的很困惑。您执行 @H_577_3@mov rbx,[rbp],但由于 rbp
没有被 @H_577_3@main 函数修改,因此它不会指向我们想要的任何位置。我只能假设这是在堆栈上获取参数的一些尝试?
老实说,在这一点上我很难过。
通常使用以下样板启动您的函数。
push rbp
mov rbp,rsp
原因是为了保护栈。现在所有引用都可以针对 rbp
完成,它在您的代码中永远不会改变(它总是指向您的堆栈帧)。它是一个被调用者保存的寄存器,所以无论如何我们都必须保存它,并在设置它之前在堆栈上这样做。
通常使用以下样板结束您的函数。
@H_577_3@mov rsp,rbp pop rbp ret
按照 AMD64 调用约定的要求,这会将堆栈指针和 rbp
恢复到它们在入口时的位置。这有一个同义词:leave
。下面的代码是等价的。
leave
ret
现在,当您使用 printf
(或任何可能使用 xmm
寄存器的函数)时,您还必须确保在调用之前堆栈在 16 字节边界上对齐。您可以假设堆栈在进入 @H_577_3@main 时对齐。 push rbp
会将它搞砸(减少 8 位),但是当您执行 call printf
时,您将再推 8 个字节(返回地址)并加速!堆栈已对齐。
我最后的建议是使用 AMD64 调用约定而不是使用堆栈。将参数放入rdi
,获取rax
中的返回值。
如果不知道您要做什么,我无法提供更多帮助。
以上是大佬教程为你收集整理的了解汇编、nasm、x86 中的 printf 函数。我不知道为什么这段代码没有打印出任何东西全部内容,希望文章能够帮你解决了解汇编、nasm、x86 中的 printf 函数。我不知道为什么这段代码没有打印出任何东西所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。