计机羊咩咩 发表于 2014-4-22 11:29:05

关于16位寄存器运算32位数据问题及计算机二进制换十进制的个人见解,有兴趣的来看看

前提: 除法溢出处理方法:比如ABCD DCBA/10在计算上必定溢出,故分为高十六位与低十六位,先求出高十六位的商,然后余数作为低十六位的最高位,与低十六位一起看成新的数值继续求商,最后高十六位的商与低十六位一起重新合并成为新的数值,即为所求。ABCDDCBA/10=ABCDDCB拆分处理后:0000 ABCD/10=ABC…D000D DCBA/10=DDBC…A然后高十六位的商与低十六位的商组合得ABCDDCB,即为所求。(想一想,其实这种思想小学就学了,回想一下我们做除法的步骤) 进制转换方法:书上说的,十六进制或二进制转换十进制均为X*Y^N次方(X为当前位的数值,Y代表进制,N代表当前位,你懂的) 然后这是我的方法:既然十进制数除以16或2直到商为0,然后自下向上分别取余组成一个数,那么相对的,其他进制也能这么做,所以嘛,看下面实例(躺在床上无意发现的,有错也正常) 例子数:902715864 (35CE59D8)求十进制,当然除以十六进制的A(10)35CE 59D8/A=0561 6F62…4(4)0561 6F62/A=0089 BE56…6(6)0089 BE56/A=000D C63B…8(8)000D C63B/A=0001 609F…5(5)0001 609F/A=0000 2343…1(1)0000 2343/A=0000 0386…7(7)0000 0386/A=0000 005A…2(2)0000 005A/A=0000 0009…0(0)0000 0009/A=0000 0000…9(9) 然后自下向上取余,组成一个新的数,就是十进制数。从上面可以看出,此时十六进制与十进制完全一样(即使在计算机上),基于此情况,我们能在屏幕上显示十进制数,只要加上30H变成ASCII码即可。 问题来了:从十六进制转换十进制来看,上述方法明显存在除法溢出,怎么办?以本文一开始的除法溢出处理方法进行处理。 可一操作就有问题了,你会发现数据拆分之后求余根本得不到正确的结果。(本人已找到问题所在)注意:本帖问题在代码下方,此处仅作本帖问题的由来。 以下是在显示器显示十进制数的源码,除上述问题外仍有瑕疵,请勿复制,及供参考。ASSUME CS:CODE DS:DATA SS:STACK DATA SEGMENT DD 5940323,29304512DB 16 DUP (1)               ;存放被数据的每一位数字DATA ENDS STACK SEGMENT DW 30 DUP(1)STACK ENDS CODE SEGMENT START:                     ;各种初始化MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV SP,20HMOV AX,0E800HMOV ES,AXMOV CX,2XOR SI,SIXOR DI,DI TWO:PUSH CXMOV AX,DS:MOV DX,DS:CALL FAR PTR SHOW_STRADD SI,4POP CXLOOP TWO OK:MOV CX,5LOOP OK MOV AX,4C00HINT 21H SHOW_STR:PUSH DXMOV CX,2                   ;初始化S1模块执行次数PUSH CXMOV BX,10 S1:                        ;无需循环的指令被放在S1模块外XOR DX,DXDIV BXADD DL,30HMOV DS:,DLINC SI                     ;SI寄存器记录了当前被处理的数据的位数MOV CX,AXJCXZ JUDGEJMP S1 JUDGE:POP CX                     ;控制S1模块执行次数SUB CX,1                   ;JCXZ PRINTF                ;若S1模块执行够两次,转到printf模块POP AX                     ;若S1模块执行未够两次,则执行此处指令并转跳回S1模块PUSH CXJMP S1 PRINTF:MOV CX,SI                  ;LOOP指令当CX为零就跳转,所以先执行该指令SUB SI,1                   ;然后(SI)-1保证读取正确的数据MOV DL,2XOR AX,AXXOR DI,DI S2:MOV AL,DS:         ;在显存写入数据MOV ES:,AL             ;数据MOV ES:,DL         ;颜色信息SUB SI,1ADD DI,2LOOP S2RETF CODE ENDSEND START
呃,看到这里,我会跟你说,上面的代码有一个S1模块,那一段是错的,还没修改。
然后我想说的是,根据除法溢出处理方法,我会拆分数据。例如 04A0 2314(77603604)如果这个数据先把高十六位求余,再组合低十六位成为新的被除数X2314 (X为高十六位的余数)此时可见,这个新的被除数直接做除法也可能会溢出。所以我们得再拆分的更细一点,先和低十六位的前两位组合吧?(X23)本帖问题来了:有没有发现,(AX)=0YYY或00YY(Y为商),那么如何处理前面的0呢?如果各位有自己笔算一下,你就会发现,寄存器数据不足四位则向前补0这个规矩真的很烦。如果不处理会使数据产生偏差,尤其是二进制化十进制的时候。
个人精力和能力有限,故在此向各位请教。

ck329054222 发表于 2014-4-22 13:06:21

:shock:懒得看一长串汇编代码。。功力不足。特来顶贴

lm2wq 发表于 2014-4-23 22:21:44

太高深,留个脚印,长大了再看~~~!~:lol:

devilzhang1 发表于 2014-4-28 11:49:38

希望楼主继续努力。。。
页: [1]
查看完整版本: 关于16位寄存器运算32位数据问题及计算机二进制换十进制的个人见解,有兴趣的来看看