废话不多说,直接开始写代码。普通指令,以及编程思想我就不介绍了。
寄存器大小位16
位能存的最大值为0FFFFH=65535
,那么如果相加的数值超过这个数产生了进位,那么寄存器不够存了,此时我们就需要用到进位加法指令 adc(add carry)
进位加法在两数相加时会带上进位,就是我们平时的算术计算时的算法一样
FFFFH+1=10000H ax=0000
进位标志 CF=1
寄存器不够存我们可以把数据存哪里?
在加一个寄存器来存也可以
此时我们可以将低16
位存ax
高16
位存dx
中那么如果两个寄存器还不够存了怎么办?寄存器数量有限。没关系我们可以直接存在内存中嘛
那么我们可以来计算下
5555 4444 3333 2222H + FFFF FFFF FFFF FFFFH=?
这个数是64
位+64
位并且产生了进位 你如果拿计算机按你会发现计算结果比第一个数还小1
为什么呢?计算器有bug
。。。哈哈
好的没关系让我们用汇编实现下看看它等于多少?
代码如下
DATAS SEGMENT
;进位加法
dw 2222H,3333H,4444h,5555h,4 dup(0FFFFH)
;将结果存在这里
dw 8 dup(0)
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV ES,AX
CALL ADD_CARRY
MOV AH,4CH
INT 21H
;===============================================
ADD_CARRY:
MOV SI,0
MOV BX,8
MOV DI,16
;循环4次
MOV CX,4
;清零CF标志位
SUB AX,AX CF=0
ADD_NUM:
MOV AX,DS:[SI] ;被加数
MOV DX,DS:[BX] ;加数
ADC AX,DX ;AX:2222H+FFFFH+CF=2221H 进位标志CF=1
MOV ES:[DI],AX ;存储位置 把2221H 放到ES[DI]位置
INC SI ;此处不用add命令是因为add 影响标志位
INC SI
INC BX
INC BX
INC DI
INC DI
LOOP ADD_NUM
ADC CX,0 ;最后一轮循环之后cx为0 在加一次CF
MOV ES:[DI],CX
RET
CODES ENDS
END START
我们运行如上代码输入u
查看代码,操作系统给我们分配了内存,call
指令的符号引用也被替换为了直接引用,java
的同学们是不是很熟悉,什么叫符号引用,什么叫直接引用这会儿秒懂。
我们u 000e
指令指向的地址看看它是什么,是不是很熟悉就是我们自己写的代码,好接下来我们直接断点到call
指令下一行
断点g 000a
回车执行
我们来查看结果使用d ds:0
,红框部分为我们安排的数据,第二行为我们的计算结果为 15555444433332221H
这个才是正确的结果。