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

博客讨论了在进行除法运算时可能出现的溢出问题,提出了将大数值拆分处理的方法。同时,文章介绍了进制转换的思路,通过不断除以目标基数并取余组成新数。作者还分享了尝试将十六进制转换为十进制过程中遇到的问题,特别是如何处理因数据不足四位而需要补零的情况。代码示例展示了转换过程中存在的问题,寻求解决方案。
摘要由CSDN通过智能技术生成

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

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

x

前提:

除法溢出处理方法:

比如ABCD DCBA/10在计算上必定溢出,故分为高十六位与低十六位,

先求出高十六位的商,然后余数作为低十六位的最高位,与低十六位一起看成新的数值继续求商,最后高十六位的商与低十六位一起重新合并成为新的数值,即为所求。

ABCDDCBA/10=ABCDDCB

拆分处理后:

0000 ABCD/10=ABC…D

000D 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,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这个规矩真的很烦。

如果不处理会使数据产生偏差,尤其是二进制化十进制的时候。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值