首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在汇编语言程序设计中执行2的补码

在汇编语言程序设计中执行2的补码
EN

Stack Overflow用户
提问于 2013-02-12 12:27:12
回答 1查看 6.9K关注 0票数 2

我正在试着做一个可以对负数进行算术运算的计算器。这里的代码用于将输入的数字转换为ASCII值。我想修改这个程序,以便在输入为负的情况下执行2的补码转换,并且它应该会产生所需的输出。

目前,这是我的计算器的流程:

-1+2=66675 (应为1)

-1-1=656745 (应为-2)

-1*-1=66757 (应为1)

有人建议我应该修改这部分代码以执行我想要的操作。我尽了最大的努力,但它不起作用。你能帮我解决这个问题吗?哦,顺便说一下,我对组装真的很陌生..

代码语言:javascript
复制
CONVERT_ASSCII PROC NEAR

    MOV AH , BYTE PTR RESULT        ;MOVE FIRST TWO BYTE OF RESULT TO AX
    MOV AL , BYTE PTR RESULT + 1

    ;AT FIRST CHECK IF AX IS POSITIVE OR NEGETIVE
    TEST EAX , 8000H                    ;CHECK THE LAST BIT . IF THATS 1 THEN AX IS NEG , OTHERWISE THATS POSITIVE
    MOV EDI , 0                     ;AT FIRST SET OUR FLAG TO ZERO
    JZ EAX_POSITIVE                 ;AX IS POSITIVE
    NEG EAX                         ;CALCULATE NEGETIVE OF AX 
    MOV EDI , 1                     ;DI INDICATES THAT AX IS NEG

EAX_POSITIVE :
    MOV ECX , 10
    LEA ESI , ASSCII_NUM
    ADD ESI , 29                        ;MOVE TO THE LAST SPACE

    MOV EBP , 0                     ;THIS IS THE COUNTER OF CHARS

    ASSCII_LOOP : MOV EDX , 0
                  DIV ECX 
                  OR DL , 30H       ;MAKE REMINDER ASSCII
                  MOV [ESI] , DL        ;PUT ASSCII IN ASSCII_NUM
                  DEC ESI
                  INC EBP           ;ADD ONE TO THE CHAR'S COUNTER
                  CMP EAX , 0       ;IF AX > 0 GOTO 
                  JA ASSCII_LOOP    ;ASSCII_LOOP

    CMP EDI , 0                     ;CHECK IF THAT WAS A NEGETIVE NUMBER
    JZ REST                         ;IF THATS NOT NEGETIVE GOTO REST
    MOV DL , '-'
    MOV [ESI] , DL                  ;ADD A MINES SIGN TO THE STRING
    DEC ESI
    INC EBP

REST :
    LEA EDI , ASSCII_NUM

    ;MOVE THE ASSCII CODE TO IT'S RIGHT PLCAE IN ASSCII_NUM
    ORDER_ASSCII : INC ESI
                   MOV AL , BYTE PTR [ESI] 
                   MOV BYTE PTR [EDI] , AL
                   INC EDI
                   DEC EBP
                   CMP EBP , 0
                   JA ORDER_ASSCII

    MOV CL , '$'           
    MOV BYTE PTR [EDI] , CL         ;AT LAST PUT A DOLLOR SIGN AT THE END OF ASSCII_NUM

    RET
CONVERT_ASSCII ENDP
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-12 13:51:41

了解问题,然后对其应用语言。我会先用C语言编写,然后再用汇编语言编写。

你提到了ASCII,但我没有看到你从ascii转换过来。

例如,当您说"-1+2“时,这是否意味着您的输入是这些项目的ASCII字符,即

代码语言:javascript
复制
0x2D,0x31,0x2B,0x32

解析它的一种方法是:

你需要识别为减号的0x2D操作,然后你点击数字1,它在ascii中是0x31。假设这些是十进制数,那么去掉0x30,例如0xF。下一个字符是+,0x2B,运算符,所以现在您可以返回并获取完整的数字1,并对其应用之前的运算符。但是你需要一个寄存器大小,这些值是8位、16位、32位还是64位?8位1是0x01,16是0x0001,依此类推,当你否定得到0xFF或0xFFFFF或0xFFFFFFFFF等。因此,当前运算符是+,0x2B,下一个字符是0x32数字2,并用0xF提取字符串的末尾2.下一个字符,所以现在应用操作-1,0xFF如果8位是0xFF+0x02 = 0x101,则加2,0x02如果8位是0x01,结果-1 +2= 1,然后你必须将其返回ascii,在这种情况下1+ 0x30 = 0x31,但对于小于10的数字来说,这只是一件容易的事情。

代码语言:javascript
复制
"-1*-1" is 0x2D,0x30,0x2A,0x2B,0x30

当你看到0x2A和0x2B行中的两个运算符时,问题就来了,在这种情况下,作为人类,我们知道在这两种情况下,减号与后面的数字求反,然后执行乘法。

更大的数字,如果你支持他们,也必须处理。

代码语言:javascript
复制
"12+34" 0x31,0x32,0x2B,0x33,0x34

0x31是一个从0x1中剥离出来的数字,但0x32也是一个数字,所以将0x1乘以10,然后将从0x32中剥离出来的2相加,得到一个0xC,然后将该数字(十进制12)的累加部分加上加号0x2B,然后以同样的方式将另一个数字从0x33中剥离出来,再乘以10,再将从0x34中剥离出来的4相加,得到小数34 ( 0x22 ),然后将这两个数字相加0x0C +0x22= 0x2E (十进制46)。在这种情况下,我假设期望的结果是0x34,0x46,即"46“的ascii字符串。你需要将0x2e除以10,因为它大于10,为了得到4,第一个数字,余数(模10)是6,也就是不大于10,所以你完成了将6设为0x36的转换。

如果目标具有NEG,则使用AND、OR、ADD、NOT和可能的NEG操作(否则使用not和add 1)。请记住,如果没有直接的NOT指令,与所有1进行异或运算就是NOT操作。(基本上是你想要针对的指令集中的基本操作)在你非常熟悉的编程语言中实现和测试你的算法,或者至少一种支持这些操作和字节处理的编程语言,让算法工作并完成,然后简单地将高级语言中的每个and、add、not、sub等操作转换成汇编语言。它可能(将)在高级语言中对解决方案进行多次迭代,然后才能类似于一种易于转换为汇编的形式。如果你现在不擅长组装,那么你就会增加完成这项任务所需的复杂性和时间。试图同时创建和调试算法并学习汇编并不是两倍的工作量,而是四倍甚至更多的工作量。分而治之。在受控环境中开发算法,然后在目标语言中实现它。

-1+2=66675 (应该是1) 0xFFFF...FFFF + 0x000...00002 = 0x1000000...000001,clips to 0x0000...00001 (我使用任意的寄存器大小) 66675 = 0x10473。不太确定你是怎么得到这样的数字的。

-1\f25 0xFFFFF....FFFFF + 0xFFFFFF...FFFFF = 0xFFFFFFF...FFFFFFE -1\f6=-1\f25 656745 -1\f6(应该是)。-2\f25 656745= 0xA0569

-1*-1=66757 (应为1)

我很想知道这些结果会是什么。

代码语言:javascript
复制
-1+1
-1+3
-2+1
-2+2
-1*-2
-1*-3
-2*-1
-2*-2

都在用你的计算器。当您这样做时,您可能会开始在结果中看到一个模式。

将问题一分为二,你确定你的数学运算计算的结果是正确的,并且只有ascii的结果是错误的吗?或者ascii的结果是工作的,数学运算被破坏了吗?十六进制很简单,八进制更容易转换,你不需要做倒退的事情来快速检查,可以在看到结果后手动反转

代码语言:javascript
复制
while(ax)
{
   dl = (ax&7)+0x30;
   string[ptr++]=dl;
   ax>>=3;
}
string[ptr]=0;

然后显示字符串。手动反转字符串,使用计算器将八进制转换为十进制,并检查结果。负2 (-2)是0xFFFFF....FFFFE,所以在八进制中你会看到,倒序为67777777777...7777777。因此,一旦你颠倒了字符串,计算器就会把你带到十六进制值0xFFFFF....FFFE。不过,使用计算器可以很容易地看到积极的结果。

(是的,我很清楚您使用的是带16位寄存器的x86 )

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14825368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档