汇编老师布置了作业,要求写两个变量的加法,在这个程序之前我们学习了闰年的程序,于是我将闰年的一段代码当做子程序直接拿过来用了,但是却出现了错误,这段子程序中用来累加数据的数据段[w]里的数据根本不是输入的数据。
经过DEBUG发现,在数据存入[w]之前的过程没有问题,唯独最后显示的[w]里的数据出现了错误。但当我把[w]换成DI寄存器就运行成功了,求问大佬是什么原因。
调用的子程序是闰年里的datacate,在我写的代码里叫mult。
我写的二变量加法的程序
DATAS SEGMENT
NUM1 DB 0DH,0AH,'Please enter the first number:',13,10,'$'
NUM2 DB 0DH,0AH,'Please enter the other number:',13,10,'$'
SUM DB 0DH,0AH,'The answer is:',13,10,'$'
buf db 8
BI DB 0
DATAS ENDS
stack segment stack
db 200 dup(0)
stack ends
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START:
MOV AX,DATAS
MOV DS,AX
OUTPUT1:
LEA DX,NUM1
MOV AH,9
INT 21H;界面输出“请输入第一个数字”
MOV DI,0;初始化寄存器DI的值,使其为零
LEA DX,BUF
mov ah,10
int 21h;键盘输入到缓冲区
MOV CH,0
MOV CL,[BUF+1];初始化CX的值,这决定了LOOP循环的次数
CALL MULT;调用MULT子程序
MOV AX,DI
OUTPUT2:
LEA DX,NUM2
MOV AH,9
INT 21H;界面输出“请输入第二个数字”
LEA DX,BUF
mov ah,10
int 21h;键盘输入到缓冲区
MOV CH,0
MOV CL,[BUF+1];初始化CX的值,这决定了LOOP循环的次数
CALL MULT
MOV AX,DI
OUTPUT3:
LEA DX,SUM
MOV AH,9
INT 21H;界面输出“结果是”
MOV AX,DI
CALL JINZHI;调用“16进制转换10进制”子程序并输出
MOV AH,4CH
INT 21H
MULT PROC NEAR
;将上面输入到缓冲区中的数据取出来进行进位计算,最终得到一个有意义的数字,比如“12”,并将12加入到W数据段中。
push cx;将cx的值压入堆栈段中(为了保留CX原始的值)
dec cx;cx-1
lea si,buf+2;获取BUF+2=004E这个偏移地址,并将该地址赋给SI
tt1:inc si;SI+1
loop tt1;返回上一条进行循环,进行一次循环,CX里的值减一,直到CX里的值为零执行下一条
pop cx;将CX的值从堆栈段里取出来
mov dh,30h
mov bl,10
mov ax,1
l1:push ax
push bx
push dx;将AX,BX,DX里的值全部存放到堆栈段中
sub byte ptr [si],dh;si作为偏移地址指向的内存中的数减去寄存器中DH的数
mov bl,byte ptr [si];将做完减法之后的内存中的数赋值给BL
mov bh,0;初始化BH的值
mul bx;执行BX和AX的乘法,乘积存放在AX中
add DI,ax
pop dx
pop bx
pop ax;将DX,BX,AX的值从堆栈段里取出来
mul bl;执行BL和AL的乘法,乘积存放在AL中
dec si;SI减一
loop l1;返回到L1进行循环
ret
MULT ENDP
JINZHI PROC NEAR;进行16进制转换10进制,使存在DI寄存器中的16进制数转成10进制并输出
MOV BX,10
MOV SI,4
remainder:
mov DX,0
DIV BX;被除数除以10
MOV [BI+SI],DL;得到的余数放在DL中,将DL中的数放在数据段里
DEC SI;SI作为计数器,每得到一个余数,SI减一
CMP AX,0
JE NEXT
JMP remainder;只有当商等于0的时候,才进行下面的程序,否则循环执行
NEXT:
INC SI;当将余数取出来时,需要SI加一,指向刚才存入的数据
MOV DL,[BI+SI];将余数赋值给DL
ADD DL,30H
MOV AH,02
INT 21H;DL加30H,得到需要显示数据的ASCII码
CMP SI,4
JB NEXT;SI小于4时,进行循环
RET
JINZHI ENDP
CODES ENDS
END START
闰年的程序:
DATA SEGMENT
infon DB 0DH,0AH,'Please input a years:$'
Y DB 0DH,0AH,'This is a leap year!$'
N DB 0DH,0AH,'This is not a leap year!$'
w dw 0
buf db 8
db ?
db 8 dup(?)
data ends
stack segment stack
db 200 dup(0)
stack ends
code segment
assume ds:data,ss:stack,cs:code
start:mov ax,data
mov ds,ax
lea dx,infon
mov ah,9
int 21h
lea dx,buf;将BUF中的地址送到DX中去
mov ah,10
int 21h;键盘输入到缓冲区
mov cl,[buf+1];buf+1=004D,将该地址的值赋给CL,CL=04
mov ch,0;初始化CH的值为零,此时CX=0004
lea di,buf+2;
call datacate;跳转到datacate所在的段地址,并将当前的IP压入栈中
call ifyears;跳转到ifyears所在的段地址,并将当前的IP压入栈中
jc a1
lea dx,n
mov ah,9
int 21h
jmp exit
a1: lea dx,y
mov ah,9
int 21h
exit: mov ah,4ch
int 21h
datacate proc near
push cx;将cx的值压入堆栈段中(为了保留CX原始的值)
dec cx;cx-1
lea si,buf+2;获取BUF+2这个偏移地址,并将该地址赋给SI
tt1:inc si;SI+1
loop tt1;返回上一条进行循环,进行一次循环,CX里的值减一,直到CX里的值为零执行下一条
pop cx;将CX的值从堆栈段里取出来
mov dh,30h
mov bl,10
mov ax,1
l1:push ax
push bx
push dx;将AX,BX,DX里的值全部存放到堆栈段中
sub byte ptr [si],dh;si作为偏移地址指向的内存中的数减去寄存器中DH的数
mov bl,byte ptr [si];将做完减法之后的内存中的数赋值给BL
mov bh,0;初始化BH的值
mul bx;执行BX和AX的乘法,乘积存放在AX中
add [w],ax
pop dx
pop bx
pop ax;将DX,BX,AX的值从堆栈段里取出来
mul bl;执行BL和AL的乘法,乘积存放在AL中
dec si;SI减一
loop l1;返回到L1进行循环
ret
datacate endp
ifyears proc near
push bx
push cx
push dx;将BX,CX,DX里的值全部存放到堆栈段中
mov ax,[w]
mov cx,ax
mov dx,0
mov bx,100;进行赋值
div bx;100作为除数
cmp dx,0
jnz lab1;余数不等于零的时候跳转到LAB1
mov ax,cx
mov bx,400
div bx;400作为被除数
cmp dx,0
jz lab2;等于零的时候跳转到LAB2
clc
jmp lab3
lab1:mov ax,cx
mov dx,0
mov bx,4
div bx
cmp dx,0
jz lab2
clc
jmp lab3
lab2:stc
lab3:pop dx
pop cx
pop bx
ret
ifyears endp
code ends
end start
你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答
本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。
因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。