gpt4 book ai didi

linux - 简单乘法函数中的推送/弹出段错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:05:44 25 4
gpt4 key购买 nike

我的老师正在和我们一起上集会速成类,而我对此毫无经验。我应该写一个简单的函数,它接受四个变量并计算 (x+y)-(z+a) 然后打印出答案。我知道这是一个简单的问题,但经过数小时的研究,我一无所获,任何朝着正确方向的努力都会非常有帮助!我确实需要使用堆栈,因为一旦我过了这一点,我就有更多的东西要添加到程序中,并且会有很多变量要存储。我在 linux 中使用 nasm 和 gcc 进行编译。 (x86 64)

(附带问题,我的“3”没有出现在寄存器 r10 中,但我在 linux 中,所以这应该是正确的寄存器……有什么想法吗?)

到目前为止,这是我的代码:

    global main

extern printf

segment .data

mulsub_str db "(%ld * %ld) - (%ld * %ld) = %ld",10,0

data dq 1, 2, 3, 4
segment .text

main:

call multiplyandsubtract
pop r9
mov rdi, mulsub_str
mov rsi, [data]
mov rdx, [data+8]
mov r10, [data+16]
mov r8, [data+24]
mov rax, 0
call printf

ret



multiplyandsubtract:

;;multiplies first function
mov rax, [data]
mov rdi, [data+8]
mul rdi
mov rbx, rdi
push rbx

;;multiplies second function
mov rax, [data+16]
mov rsi, [data+24]
mul rsi
mov rbx, rsi
push rbx

;;subtracts function 2 from function 1
pop rsi
pop rdi
sub rdi, rsi
push rdi
ret

最佳答案

push in the right direction

不错的双关语!

你的问题是你显然不知道 ret 正在使用堆栈作为返回地址。因此 push rdi; ret 只会转到 rdi 中的地址,而不会返回给您的调用者。由于这不太可能是有效的代码地址,因此您会遇到一个不错的段错误。

要从函数返回值,只需将结果保存在寄存器中,标准调用约定通常使用 rax。这是一个可能的版本:

    global main

extern printf

segment .data

mulsub_str db "(%ld * %ld) - (%ld * %ld) = %ld",10,0

data dq 1, 2, 3, 4
segment .text

main:
sub rsp, 8
call multiplyandsubtract
mov r9, rax
mov rdi, mulsub_str
mov rsi, [data]
mov rdx, [data+8]
mov r10, [data+16]
mov r8, [data+24]
mov rax, 0
call printf
add rsp, 8

ret



multiplyandsubtract:

;;multiplies first function
mov rax, [data]
mov rdi, [data+8]
mul rdi
mov rbx, rdi
push rbx

;;multiplies second function
mov rax, [data+16]
mov rsi, [data+24]
mul rsi
mov rbx, rsi
push rbx

;;subtracts function 2 from function 1
pop rsi
pop rdi
sub rdi, rsi
mov rax, rdi
ret

PS:请注意,我还根据 ABI 修复了堆栈对齐。众所周知,printf 对此也很挑剔。

关于linux - 简单乘法函数中的推送/弹出段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41948181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com