如何创建仅使用寄存器来表示标识符的汇编语言?

时间:2011-10-21 15:40:19

标签: assembly x86 masm

澄清问题:

salary = reghours * 3 + overtimehours * 2 - benifit * 3

它不能使用变量(.data)...

这是我到目前为止所创造的:

    mov eax,3
    mov ebx,2
    mul ebx
    call dumpRegs

    mov ecx,2
    mov ebx,2
    mul ebx
    call dumpRegs

    mov edx,3
    mov ebx,5
    mul ebx
    call dumpRegs

好的,上面的两条指令计算是正确的,edx寄存器继续为零?

我的问题是,如何计算工资,包括reg + reg - reg与reg的总和?

2 个答案:

答案 0 :(得分:2)

第1步:按顺序执行三个较高优先级操作中的每个操作,这些操作在进入第2步时会有意义:

benifit * 3        // question: why would you do this calculation first?
reghours * 3
overtimehours * 2

在每次计算之后,将中间结果推到堆栈上。

第2步:完成所有三项计算后,通过从堆栈中弹出三个中间结果中的每一个来开始计算最终结果。

Voila:没有使用.data空间。这个家庭作业练习可能是为了让你理解和使用堆栈。顺便说一句,你没有检查作业标签。

您也可以通过将中间结果保存在寄存器中来解决此问题,但这有点困难:即,它需要您仔细考虑要保存的中间结果以及何时计算和保存它们。

答案 1 :(得分:2)

参考3-746 Vol. 2A,我们看到您使用的mul指令是:

F7 /4 MUL r/m32    Unsigned multiply (EDX:EAX ← EAX ∗ r/m32).

换句话说,eax乘以给定的操作数(在本例中为ebx),得到一个存储在edx:eax中的64位结果,即32个最高有效位是存储在edx中,32个存储在eax中。

所以:

    mov eax,3
    mov ebx,2
    mul ebx

edx:eax设置为6 = 00000000:00000006,这就是清除edx的原因。

保留寄存器的标准方法是将它们压入堆栈(push edx),然后将其恢复(pop edx)。由于程序中没有那么多变量,因此您也可以使用一个不需要操作数和结果的有符号乘法指令,它们位于edxeax中。

e.g。

IMUL r32, r/m32, imm32  doubleword register ← r/m32 ∗ immediate doubleword. 

这使您可以imul eax, eax, 3eax乘以3。

将其与@Pete Wilson's answer结合使用以实际计算该值。