Assembly 第二次使用mul后的分段错误

Assembly 第二次使用mul后的分段错误,assembly,nasm,Assembly,Nasm,我在汇编程序中完全是noob,我尝试创建函数并在C中使用它。这个函数得到3个变量a,x,y,它们是包含两个64位int的结构。我想返回a+x*y。不幸的是,这段代码是NASM导致的segfault %define a1 [rdi] %define a2 [rdi+8] %define x1 [rsi] %define x2 [rsi+8] %define y1 [rdx] %define y2 [rdx+8] %define output1 rax %define output2 rdx %de

我在汇编程序中完全是noob,我尝试创建函数并在C中使用它。这个函数得到3个变量a,x,y,它们是包含两个64位int的结构。我想返回a+x*y。不幸的是,这段代码是NASM导致的segfault

%define a1 [rdi]
%define a2 [rdi+8]
%define x1 [rsi]
%define x2 [rsi+8]
%define y1 [rdx]
%define y2 [rdx+8]
%define output1 rax
%define output2 rdx
%define res1 r8
%define res2 r9

global abc

abc:

mov output1, x1
mul qword y1
mov res1, output1
mov output1, x1
mul qword y2
mov res2, output1
mov output1, x2
mul qword y1
add res2, output1
mov output1, res1
mov output2, res2


ret

删除带有第二个和第三个mul的行可以让我运行程序而不会出现SEGFULT。

如果你解开上面的宏定义,你最终会得到这样的结果,这就是处理器实际试图执行的:

mov rax, [rsi]
mul qword [rdx]      <--- no segfault here
mov r8, rax
mov rax, [rsi]
mul qword [rdx+8]    <--- segfault here
mov r9, rax
mov rax, [rsi+8]
mul qword [rdx]      <--- segfault here
add r8, rax
mov rax, r8
mov rdx, r9

在调试器中单步执行代码。仔细观察寄存器。我还建议不要使用%define隐藏寄存器,这样在读取时很难遵循真正的机器代码,并且由于某些指令(如
mul
)具有固定寄存器,您必须不断检查某些define是否与指令冲突。在正常寄存器可见的源代码中,您只需快速查看上面几行即可。这些寄存器的“名称”属于注释IMHO。更正:(1)这不是心灵调试。问题中提供了所需的所有信息。(2) 心灵调试是最糟糕的调试。在心理调试中,你在胡乱猜测。这可不是我最喜欢的消遣。(3) 我们现在做的不是心理调试。这只是在心理上模拟一台计算机。好吧,这是公平的,这只是简单的代码分析。但是我已经读了你的博客很多年了,我仍然会说你确实喜欢心理调试,这纯粹是基于你在上面写文章的次数;-)
%define a1 [rdi]
%define a2 [rdi+8]
%define x1 [rsi]
%define x2 [rsi+8]
%define y1 [r10]         ; Change which register we're using as the
%define y2 [r10+8]       ; pointer to 'r10'.
%define output1 rax
%define output2 rdx
%define res1 r8
%define res2 r9

global abc

abc:
    mov r10, rdx         ; Preserve the real pointer to 'y1' in 'r10'.

    mov output1, x1
    mul qword y1
    mov res1, output1
    mov output1, x1
    mul qword y2
    mov res2, output1
    mov output1, x2
    mul qword y1
    add res2, output1
    mov output1, res1
    mov output2, res2

    ret