装配MASM处理负整数

时间:2013-11-10 04:48:23

标签: assembly x86 masm twos-complement irvine32

我被指示在程序集中编写一个程序,该程序将执行以下算法:

<(>(A + B)/ C)*((D-A)+ E)

当没有负值发挥作用时,我成功地做到了这一点,但假设A = 5,B = 4,C = 3,D = 2,E = 1.这给了我们((5 + 4) )/ 3)*((2 - 5)+ 1)或-6。

这是我需要帮助的地方。我已经做了一些研究,并且发现了2个赞美是一个解决方案,但我不确定是否将它实现到我的代码中。

如果有人可以帮助我,我会非常感激!

INCLUDE Irvine32.inc
; ((A + B) / C) * ((D - A) + E)
.data
valA dword 1
valB dword 2
valC dword 3
valD dword 4
valE dword 5

.code
main PROC

    mov ecx, valA
    add ecx, valB
    mov edx, valC
    call Divide
    mov ecx, eax
    mov edx, valD
    sub edx, valA
    add edx, valE
    call Multiply

    exit

main ENDP

*除法和乘法程序分别进行除法和乘法。

2 个答案:

答案 0 :(得分:2)

Irvines的WriteDec应由WriteInt替换,DIV将参数parent.Xrm.Page.getAttribute()作为签名号码处理。

在CPU内部,负面&#34; -2&#34;和积极的&#34; 4294967294&#34;转换为相同的值:0xFFFFFFFE。 IDIV正向执行除法6 / -2(6/4294967294)并获得结果0 = 0x00000000,MUL结果正确:-3 = 0xFFFFFFFD。

IMULIMUL在结果的高位部分(EAX)不同。由于在这种情况下不需要高部分,因此不必使用ADD

对于有符号和无符号数字,SUBWriteInt没有不同版本。这是引入2&amp;补码编码的主要原因。这只是一个解释:如果程序员决定这应该是签名号码,那么它是一个签名号码。如果他/她/它决定这是一个无符号数,那么它是一个无符号数。 CPU并不关心这些事情 - 结果总是一样的。

以下是IDIVIMULNEG的示例:

EDX

需要进行2的补码计算才能得到数字的绝对值。例如。 -2的表示有两部分:符号(&#39; - &#39;)和绝对值(&#39; 2&#39;)。获得绝对值的一种简单方法是查看符号位,数字的最左位,并跳转到适当的位置。计算本身仅由WriteDec执行。

IDIVIMULhere的示例:

; ((A + B) / C) * ((D - A) + E)
INCLUDE Irvine32.inc

.DATA
valA dword 5
valB dword 4
valC dword 3
valD dword 2
valE dword 1

.CODE
main PROC
    mov ecx, valA
    add ecx, valB
    mov edx, valC
    call Divide

    mov ecx, eax
    mov edx, valD
    sub edx, valA
    add edx, valE
    call Multiply

    call WriteInt           ; Write a positive or negative number

    exit
main ENDP

Divide PROC USES ECX EDX    ; EAX = ECX / EDX
    mov eax, ecx
    mov ecx, edx
    xor edx, edx
    idiv ecx                ; Signed division, e.g 6/-3 = -2
    ret
Divide ENDP

Multiply PROC USES ECX EDX  ; EAX = ECX * EDX
    mov eax, edx
    imul ecx                ; Signed multiplication
    ret
Multiply ENDP

END main

这是一个算法来获取没有跳转的EAX的绝对值:

; ((A + B) / C) * ((D - A) + E)
INCLUDE Irvine32.inc

.DATA
valA dword 5
valB dword 4
valC dword 3
valD dword 2
valE dword 1

.CODE
main PROC
    mov ecx, valA
    add ecx, valB
    mov edx, valC
    call Divide

    mov ecx, eax
    mov edx, valD
    sub edx, valA
    add edx, valE
    call Multiply

    test eax, eax           ; Set the flags according to (EAX AND EAX)
    jns J1                  ; Skip the next block if EAX is positive (no sign)

        ; EAX is negative
        push eax            ; Preserve EAX
        mov al, '-'         ; Write the letter '-'
        call WriteChar      ; http://programming.msjc.edu/asm/help/index.html?page=source%2Firvinelib%2Fwritechar.htm
        pop eax             ; Restore EAX
        neg eax             ; 2's complement

    J1:
    call WriteDec           ; Write EAX as positive number

    exit
main ENDP

Divide PROC USES ECX EDX    ; EAX = ECX / EDX
    mov eax, ecx
    mov ecx, edx
    xor edx, edx
    idiv ecx                ; signed division, e.g 6/-3 = -2
    ret
Divide ENDP

Multiply PROC USES ECX EDX  ; EAX = ECX * EDX
    mov eax, edx
    imul ecx                ; signed multiplication
    ret
Multiply ENDP

END main

答案 1 :(得分:1)

在二进制补码机器上,addsub操作对于有符号和无符号数量实际上是相同的,因此程序的那些部分不需要更改。有标记的除法和乘法的具体指令,因此请确保函数使用它们(或直接使用它们)。