程序集MASM处理负整数 [英] Assembly MASM Dealing with Negative Integers

查看:169
本文介绍了程序集MASM处理负整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被指示要编写一个程序集,该程序将执行以下算术运算:

I was instructed to write a program in assembly that will carry out the following arithmetic:

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

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

当没有负值出现时,我已成功完成此操作,但假设A = 5,B = 4,C = 3,D = 2和E =1.这给出了((5 + 4 )/3)*((2-5)+1)或-6.

I've succeeded in doing this when no negative values come into to play, but suppose A = 5, B = 4, C = 3, D = 2, and E = 1. This gives us ((5 + 4) / 3) * ((2 - 5) + 1) or -6.

这是我需要帮助的地方.我进行了一些研究,发现2的称赞是一种解决方案,但是我不确定将其实现到我的代码中.

this is where I need help. I've done some research, and have found 2's compliment to be a solution, but I'm not sure to implement it into my code.

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

If someone could help me, I'd be very grateful!


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

*除法和乘法过程分别除法和乘法.

*Divide and Multiply Procedures divide and multiply respectively.

推荐答案

Irvines的

Irvines's WriteDec should be replaced by WriteInt which handles the argument EAX as signed number.

在CPU内部,负的"-2"和正的"4294967294"被转换为相同的值:0xFFFFFFFE. DIV 积极执行6/-2除法(6/4294967294)并获得结果0 = 0x00000000,且 IDIV 结果正确:-3 = 0xFFFFFFFD.

Inside the CPU, the negative "-2" and the positive "4294967294" are transformed to the same value: 0xFFFFFFFE. DIV performs the division 6/-2 positively (6/4294967294) and gets the result 0 = 0x00000000, with IDIV the result is correct: -3 = 0xFFFFFFFD.

MUL IMUL .

MUL and IMUL differ in the high part of the result (EDX). Since the high part is not needed in this case, it is not mandatory to use IMUL.

ADD

There are no different versions of ADD and SUB for signed and unsigned numbers. This was the main reason for introducing the 2's complement coding. It's just a thing of interpretation: if the programmer decides that this should be a signed number, then it is a signed number. If he/she/it decides that this is an unsigned number, then it is an unsigned number. The CPU doesn't care about such things - the results will be always the same.

以下是 WriteInt IDIV

Here's an example with WriteInt, IDIV and IMUL:

; ((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

需要2的补数计算才能得出数字的绝对值.例如. -2的表示形式有两个部分:一个符号('-')和一个绝对值('2').获取绝对值的一种简单方法是查看符号位(数字的最左边的位),并进行适当的跳转.计算本身仅由 NEG 执行.

A 2's complement calculation is needed to get the absolute value of the number. E.g. the representation of -2 has two parts: a sign ('-') and an absolute value ('2'). A simple way to get the absolute value is to look at the sign bit, the leftmost bit of the number, and to jump appropriate. The calculation itself is performed just by NEG.

带有WriteDec IDIV 这里是一种无需跳跃即可获取EAX绝对值的算法:

Here is an algorithm to get the absolute value of EAX without jump:

cdq
xor eax, edx
sub eax, edx

这篇关于程序集MASM处理负整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆