鱼C论坛

 找回密码
 立即注册
查看: 5069|回复: 3

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

[复制链接]
发表于 2014-4-22 11:29:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
前提:
除法溢出处理方法:
比如ABCD DCBA/10在计算上必定溢出,故分为高十六位与低十六位,
先求出高十六位的商,然后余数作为低十六位的最高位,与低十六位一起看成新的数值继续求商,最后高十六位的商与低十六位一起重新合并成为新的数值,即为所求。
ABCDDCBA/10=ABCDDCB
拆分处理后:
0000 ABCD/10=ABC…D
000D DCBA/10=DDBC…A
然后高十六位的商与低十六位的商组合得ABCDDCB,即为所求。(想一想,其实这种思想小学就学了,回想一下我们做除法的步骤)
进制转换方法:
书上说的,十六进制或二进制转换十进制均为X*Y^N次方(X为当前位的数值,Y代表进制,N代表当前位,你懂的)
然后这是我的方法
既然十进制数除以162直到商为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,29304512
DB 16 DUP (1)               ;存放被数据的每一位数字
DATA ENDS
STACK SEGMENT
DW 30 DUP(1)
STACK ENDS
CODE SEGMENT
START:                     ;各种初始化
MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV SP,20H
MOV AX,0E800H
MOV ES,AX
MOV CX,2
XOR SI,SI
XOR DI,DI
TWO:
PUSH CX
MOV AX,DS:[SI]
MOV DX,DS:[SI+2]
CALL FAR PTR SHOW_STR
ADD SI,4
POP CX
LOOP TWO
OK:
MOV CX,5
LOOP OK
MOV AX,4C00H
INT 21H
SHOW_STR:
PUSH DX
MOV CX,2                   ;初始化S1模块执行次数
PUSH CX
MOV BX,10
S1:                        ;无需循环的指令被放在S1模块外
XOR DX,DX
DIV BX
ADD DL,30H
MOV DS:[SI+8],DL
INC SI                     ;SI寄存器记录了当前被处理的数据的位数
MOV CX,AX
JCXZ JUDGE
JMP S1
JUDGE:
POP CX                     ;控制S1模块执行次数
SUB CX,1                   ;
JCXZ PRINTF                ;S1模块执行够两次,转到printf模块
POP AX                     ;S1模块执行未够两次,则执行此处指令并转跳回S1模块
PUSH CX
JMP S1
PRINTF:
MOV CX,SI                  ;LOOP指令当CX为零就跳转,所以先执行该指令
SUB SI,1                   ;然后(SI)-1保证读取正确的数据
MOV DL,2
XOR AX,AX
XOR DI,DI
S2:
MOV AL,DS:[SI+8]           ;在显存写入数据
MOV ES:[DI],AL             ;数据
MOV ES:[DI+1],DL           ;颜色信息
SUB SI,1
ADD DI,2
LOOP S2
RETF
CODE ENDS
END START

呃,看到这里,我会跟你说,上面的代码有一个S1模块,那一段是错的,还没修改。

然后我想说的是,根据除法溢出处理方法,我会拆分数据。
例如 04A0 2314(77603604)
如果这个数据先把高十六位求余,再组合低十六位成为新的被除数X2314 (X为高十六位的余数)
此时可见,这个新的被除数直接做除法也可能会溢出。
所以我们得再拆分的更细一点,先和低十六位的前两位组合吧?(X23)
本帖问题来了:
有没有发现,(AX)=0YYY或00YY(Y为商),那么如何处理前面的0呢?
如果各位有自己笔算一下,你就会发现,寄存器数据不足四位则向前补0这个规矩真的很烦。
如果不处理会使数据产生偏差,尤其是二进制化十进制的时候。

个人精力和能力有限,故在此向各位请教。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-22 13:06:21 | 显示全部楼层
:shock:懒得看一长串汇编代码。。功力不足。特来顶贴
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-4-23 22:21:44 | 显示全部楼层
太高深,留个脚印,长大了再看~~~!~:lol:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-4-28 11:49:38 | 显示全部楼层
希望楼主继续努力。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-26 08:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表