2015-01-21 81 views
1

我一直在学习NASM几个星期。一切进展顺利 - 我现在一直专注于64位。推送寄存器纯粹用于短期保存可以吗?

早些时候我注意到rdx寄存器在我执行mul指令时被搞乱了。

基本上,该代码是与此类似:

; Code using RDX is up here 

mov rax,2 
mov rbx,10 

mul rbx 

; Code using RDX again is down here .. but the value is now zero 

所以,很显然RDX有事情做与mul。为了解决这个问题,我改变了代码,以这样的:

push rdx 
mov rax,2 
mov rbx,10 

mul rbx 

pop rdx 

基本上,我保留之前mul指令与它弄乱堆栈中的寄存器...然后弹出回来之后(因为我不不在乎rdx中的值。我希望它成为我想要的值)。

我的问题是:这可以吗?这是常见的吗?我没有这么做很久......但感觉有点奇怪。

我可以改为使用局部变量来进行一些计算而不是寄存器..这可能会解决这个问题,而无需在短时间内将它推入栈中......但问题依然存在。

奖金问题:是否有某个地方可以全面了解这些指令在64位环境中的作用?我似乎无法找到一个参考,它实际上告诉我用简单的英语在mul指令后rdx寄存器中发生了什么。

+0

n×n乘有2n结果。这种类型的push/pop是告诉机器代码是由人类而不是机器编写的方式:)它看起来像解决问题的天真的方式,事实并非如此。堆栈内存访问有3个周期延迟。机器将寻找一种方法将值存储在另一个寄存器中,如r9-r15或xmm0-15。或者考虑使用SIMD指令的可能性,以便同时得到4个乘积:) – 2015-01-21 12:13:45

+0

是的,这是我的小脑子现在正在实现的东西:)我试图远离附加寄存器('r9'等) ),这样我就可以轻松地把它移植到32位的时候。我发现有很多原因可能不是一个好主意 - 所以我会重新访问我的注册使用情况。谢谢:) – 2015-01-21 21:43:10

回答

3

有什么地方可以完全覆盖这些指令在64位环境中的功能吗?我似乎无法找到真正告诉我用简单的英语基准是什么MUL指令

Intel's manual把它相当清楚地后发生的RDX寄存器:

MUL r/m64 Unsigned multiply (RDX:RAX ← RAX ∗ r/m64). 

也就是说,RDX将保存产品的最重要的64位。

至于你的主要问题;如果可以,请使用不同的寄存器。如果你不能,那么你需要以某种方式备份RDX的值,使用堆栈是一个简单的方法。

+0

谢谢。这听起来很愚蠢,但我昨晚找不到手册的相关部分:/感谢您的解释。有时你只需要有人指出你明显的方向! – 2015-01-21 21:40:31

1

在这种情况下推动/弹出是完全合理的。

为什么不使用imul rax,rbx甚至imul rax,10?这些不是混乱与RDX的。

+0

或'lea rax,[rax + rax * 4] \ shl rax' – harold 2015-01-21 12:01:22

+0

有趣 - 我没意识到我可以做到这一点。我也会玩这个。 – 2015-01-21 21:41:26

1

这并不总是好的。例如,在win64上,随机推送和弹出不在序言或epilog中打开展开,如果在堆栈指针恢复正常之前发生异常,那么事情会变得非常错误。

虽然在这种情况下并不是真的需要,因为您可以繁殖而不会影响rdx

+0

感谢Windows提及 - 我甚至没有考虑过!我有很多东西要学习:) – 2015-01-21 21:41:03