1
以下程序完成字运算w=x+y-z,请填空。
Data segment
x dw 3000h
y dw 2000h
z dw 1000h
w dw ?
Data ends
Stack segment para stack
Db 10h dup(0)
Stack ends
Code segment
Assume cs: (1) ,ds: (2) ,ss: (3)
kaishi: mov ax, (4)
mov (5) ,ax
mov ax,x
add ax, (6)
sub ax, (7)
mov w, (8)
(9) ends
End (10)
Data segment
x dw 3000h
y dw 2000h
z dw 1000h
w dw ?
Data ends
Stack segment para stack
Db 10h dup(0)
Stack ends
Code segment
Assume cs: code_seg, ds: data_seg, ss: stack_seg
kaishi: mov ax, data_seg
mov ds, ax
mov ax, x
add ax, y
sub ax, z
mov w, ax
code_seg ends
End kaishi
填空部分如下:
code_seg
data_seg
stack_seg
data_seg
ds
y
z
ax
code_seg
kaishi
下面是每行汇编代码的含义
Data Segment (数据段)
Data segment
x dw 3000h
y dw 2000h
z dw 1000h
w dw ?
Data ends
Data segment 和 Data ends:定义数据段,包含程序中使用的所有数据。
x dw 3000h:定义一个名为 x 的字(word,16位)变量,初始值为 3000h。
y dw 2000h:定义一个名为 y 的字变量,初始值为 2000h。
z dw 1000h:定义一个名为 z 的字变量,初始值为 1000h。
w dw ?:定义一个名为 w 的字变量,初始值未知(未初始化)。
Stack Segment (堆栈段)
Stack segment para stack
Db 10h dup(0)
Stack ends
Stack segment para stack 和 Stack ends:定义堆栈段,包含程序运行期间使用的堆栈。
Db 10h dup(0):分配16个字节的堆栈空间,并用0初始化。
Code Segment (代码段)
Code segment
Assume cs: code_seg, ds: data_seg, ss: stack_seg
kaishi:
mov ax, data_seg
mov ds, ax
mov ax, x
add ax, y
sub ax, z
mov w, ax
code_seg ends
End kaishi
Code segment 和 code_seg ends:定义代码段,包含程序的所有指令。
Assume cs: code_seg, ds: data_seg, ss: stack_seg:假定代码段寄存器(CS)指向 code_seg,数据段寄存器(DS)指向 data_seg,堆栈段寄存器(SS)指向 stack_seg。
Main Program (主程序)
kaishi::程序的起始标签,相当于C语言的 main 函数。
mov ax, data_seg:将数据段的段地址加载到AX寄存器。
mov ds, ax:将AX寄存器的值(数据段地址)加载到DS寄存器,使DS指向数据段。
mov ax, x:将变量 x 的值(3000h)加载到AX寄存器。
add ax, y:将变量 y 的值(2000h)加到AX寄存器的值上,AX现在为5000h。
sub ax, z:将变量 z 的值(1000h)从AX寄存器的值中减去,AX现在为4000h。
mov w, ax:将AX寄存器的值(4000h)存储到变量 w 中。
Ending the Code Segment (结束代码段)
code_seg ends:标记代码段的结束。
End kaishi:表示程序的结束,并指定程序的入口点为 kaishi。
2
X、Y都是字,若X>Y,求X-Y的值放于Y中,否则Y中放X的值。请填空(注意答案中不要有空格或其它符号):
MOV AX,X
(1) AX,Y
(2) NEXT1
SUB AX, __(3)___
MOV Y,AX
__(4)___ OVER
(5):MOV Y,AX
OVER:MOV AH,4CH
INT 21H
MOV AX, X ; 将X的值放入AX寄存器
CMP AX, Y ; 比较AX寄存器中的值和Y的值
JG NEXT1 ; 如果AX > Y,跳转到标签NEXT1
MOV AX, Y ; 如果AX <= Y,将Y的值放入AX寄存器
JMP OVER ; 无条件跳转到标签OVER
NEXT1:
SUB AX, Y ; 计算AX - Y,并将结果放入AX寄存器
MOV Y, AX ; 将AX寄存器中的值放入Y中
OVER:
MOV AH, 4CH ; 退出程序,设置退出代码为4Ch
INT 21H ; DOS中断,退出程序
3
X、Y是字,求X-Y的绝对值放于字Z中。请填空(答案前后不要有空格或其它符号):
MOV AX , X
__(1)__ AX,Y
__(2)__ NEXT
MOV BX , Y
SUB BX , __(3)___
MOV Z,BX
__(4)__ OVER
(5): SUB AX , Y
MOV Z , AX
OVER:MOV AH,4CH
INT 21H
MOV AX , X ; (1) 将变量 X 的值移动到寄存器 AX 中
CMP AX, Y ; (2) 比较寄存器 AX 和 Y 中的值
JL NEXT ; (3) 如果 AX < Y,则跳转到 NEXT 标签处
MOV BX , Y ; 将变量 Y 的值移动到寄存器 BX 中
SUB BX , AX ; (4) 用寄存器 BX 减去 AX 的值(Y - X)
MOV Z , BX ; 将结果移动到变量 Z 中
JMP OVER ; (5) 跳转到 OVER 标签,结束程序
NEXT:
SUB AX , Y ; 将寄存器 AX 减去 Y 的值(X - Y)
MOV Z , AX ; 将结果移动到变量 Z 中
OVER:
MOV AH , 4CH ; 将退出代码 4CH 移动到 AH 中
INT 21H ; 中断 21H,结束程序
4
以下程序将数据段中bin1字数据以2进制数在屏幕输出,请填空(注意不要填写任何多余符号,包括空格):
1
bin1 dw 0ab48h
asc1 db 10h dup(0),‘$’
iannn.
mov dx.bin1
mov di,offset asc1
mov cx,10h
lop:_(1),1
mov al,dl
(2).01h
add (3),30h
mov(4),al
(5)diloop loplea dx,(6)mov ah.09hint 21hmov ah,4chint 21h
code ends
end start
正确答案:(1) rol dx(2) and al(3) al(4) diinc(6) asc1
bin1 dw 0ab48h ; 数据段中的 bin1 字数据
asc1 db 10h dup(0),'$' ; 数据段中的 asc1 字符串,长度为 10h,末尾为 '$'
start:
mov dx, bin1 ; 将 bin1 的地址加载到 dx 寄存器
mov di, offset asc1 ; 将 asc1 的偏移地址加载到 di 寄存器
mov cx, 10h ; 设置循环计数器为 10h
lop: ; 循环开始
mov ax, [dx] ; 将 dx 寄存器指向的内存地址处的 16 位数据加载到 ax 寄存器
shr al, 4 ; 右移 al 寄存器的内容 4 位,相当于将高 4 位移到低 4 位
and al, 0fh ; 将 al 寄存器的内容与 0fh 进行按位与运算,相当于保留低 4 位
add al, 30h ; 将 al 寄存器的内容加上 30h,将其转换为 ASCII 码
mov [di], al ; 将 al 寄存器的内容存储到 di 寄存器指向的内存地址处
inc di ; 递增 di 寄存器,指向下一个字符存储位置
inc dx ; 递增 dx 寄存器,指向下一个数据段位置
loop lop ; 循环,直到 cx 寄存器的值减为零
mov ah, 09h ; 调用 DOS 功能,用于在屏幕上显示字符串
lea dx, asc1 ; 将 asc1 的地址加载到 dx 寄存器
int 21h ; 调用 DOS 中断
mov ah, 4ch ; 调用 DOS 功能,用于程序退出
int 21h ; 调用 DOS 中断