记录一下在学习汇编的过程中遇到的有意思的习题
2021/10/05
1.编写程序向内存0:200~0:23F依次传送数据0~63。
assume cs:code
code segment
start:mov ax,0H
mov ds,ax ;ax=ds*16+bx
mov bx,200H ;十六进制
mov dx,0 ;初始化累加器dx=0
mov cx,64 ;设置循环次数64
s: mov ds:[bx],dl
inc dl ;dx自增
inc bx ;bx自增 ds:bx指向下一个单元
loop s
mov ax,4c00H
int 21H
code ends
end start
2021/10/07
2.计算ffff:0~ffff:b单元中的数据的和,结果存放在dx中
;计算ffff:0~ffff:b单元中的数据的和,结果存放在dx中
assume cs:code
code segment
start: mov ax,0ffffh
mov ds,ax ;设置段地址
mov bx,0 ;ds:bx指向 ffff:0
mov dx,0 ;设置累加器dx=0
mov cx,0bH ;循环12次
s:mov al,[bx]
mov ah,0
add dx,ax ;dx=(ds)*16+bx
inc bx ;ds:bx指向下一个单元
loop s
mov ax,4c00H
int 21H
code ends
end start
2021/11/1
3.试编写一程序计算以下表达式:
(提示:可以采用移位指令或者乘除法指令)
Z=(3X十Y-5)/2
;Z=(3X十Y-5)/2
assume cs:code,ds:data
data segment
VARX dw 15
VARY dw 10
VARZ dw ?
data ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,VARX ;ax<-x
shl ax,1 ;ax<-ax*2
add ax,VARX ;ax<-ax*2+ax
add ax,VARY ;3*x+y
sub ax,5 ;3*x+y-5
shr ax,1 ;(3X十Y-5)/2
mov VARZ,ax
mov ax,4c00h
int 21h
code ends
end start
4.设AL寄存器的初值为0A9H,将AL寄存器中的8位数分成2组,每组4位,编程实现把这两组数从高到低分别放在AL、BL中。
assume cs:code
code segment
start:
mov ax,0A9H
mov bl,0AH
div bl
mov bl,ah ;bx=0009H
mov ax,0A9H
mov cl,4
shr al,cl ;al=000AH
mov ax,4c00h
int 21h
code ends
end start
2021/11/2
5.《汇编语言》王爽第四版,检测点9.1(1)(2)
(1)若要使程序中的jmp指令执行后,CS:IP指向程序的第一条指令,在data段中应该定义哪些数据
assume cs:code
data segment
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
jmp word ptr [bx+1]
code ends
end start
指向第一条指令,则要使IP的值为0000H即可,而jmp word ptr为段内转移指令,相当于把IP值赋值为后面内存单元的值,故只需要第一个字节为0即可。
assume cs:code
data segment
db 4 dup(0)
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
jmp word ptr [bx+1]
code ends
end start
调试
(2)补全程序,使jmp指令执行后,CS:IP指向程序的第一条指令
assume cs:code
data segment
dd 12345678H
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov [bx],bx
mov [bx+2],cs
jmp dword ptr ds:[0]
mov ax,4c00H
int 21H
code ends
end start
执行jmp指令后指向第一条指令,CS段没有改变,只需要改变IP值为0000H。而段间转移相当于把内存地址开始的前两个字节赋值给IP,后面的两字节赋值给CS
调试
2021/11/08
6.编程实现以下功能:双字变量A,B,相加结果放入双字变量C中,相减结果放入双字变量D中。
assume cs:code,ds:data
data segment
A dd 12345678H
B dd 98765432H
C dd ?
D dd ?
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
clc
mov cx,2
s:mov ax,word ptr [A+si]
adc ax,word ptr [B+si]
mov word ptr [C+si],ax
inc si
inc si
loop s
clc
mov si,0
mov cx,2
s0:mov ax,word ptr [A+si]
sbb ax,word ptr [B+si]
mov word ptr [D+si],ax
inc si
inc si
loop s0
mov ax,4c00h
int 21h
code ends
end start
7.编程实现功能两个128位数据相加
assume cs:code;ds:data
data segment
a dw 1,2,3,4,5,6,7,8
b dw 8,7,6,5,4,3,2,1
c dw 8 dup(0)
data ends
code segment
start: mov ax,data
mov ds,ax
clc ;清除标志位CF的值
mov si,14
mov cx,8
s:mov ax,ds:a[si]
adc ax,ds:b[si] ;ax=ax+b[si]+cF
mov ds:c[si],ax
dec si
dec si ;sub si,2
loop s
mov ax,4c00H
int 21H
code ends
end start
8.在数据段内连续存放着10个字节型无符号二进制数,编写一段程序,求出该10个数之和,并将结果存放在寄存器AX中。
assume cs:code,ds:data
data segment
A db 1B,10B,11B,110B,111B,101B,100B,1111B,1110B,1000B
data ends
code segment
start: mov ax,data
mov ds,ax
mov ax,0
mov si,0
clc
mov cx,10
s:adc al,byte ptr [A+si]
inc si
loop s
mov ax,4c00H
int 21H
code ends
end start
2021/11/16
1.统计分数
assume cs:code,ds:data
data segment
Fenshu db 80,45,60,77,88,99,58
a db 0
B db 0
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
mov cx,7
s:cmp byte ptr[bx],60
jb next ;小于60转移到next
inc a ;a=5
jmp last
next:inc B
jmp last
last:inc bx
loop s
mov ax,4c00H
int 21H
code ends
end start
- 编写一个程序,将包含任意字符,以0结尾的字符串的小写字母转变成大写字母。
assume cs:code,ds:data
data segment
db "Today is a good day 0"
data ends
code segment
start:mov ax,data
mov ds,ax
mov bx,0
s1:cmp byte ptr[bx],'0'
je last
s2:cmp byte ptr[bx],'a'
jb s5
s3:cmp byte ptr[bx],'z'
ja s5
s4:sub byte ptr[bx],20H
s5:inc bx
jmp s1
last:mov ax,4c00H
int 21H
code ends
end start
3.编写程序实现以下功能:字变量X与字变量Y比较大小(无符号数),如果大于则字变量z值为1;如果等于,则z值为0;小于则z为-1。
assume cs:code,ds:data
data segment
x dw 5
y dw 7
z dw 0
data ends
code segment
start:mov ax,data
mov ds,ax
mov ax,x
mov bx,y
s1:cmp ax,bx ;不低于就转移
jnb s2a
mov z,-1
jmp last
s2:cmp ax,bx ;不deng就转移
jne s3
mov z,0
jmp last
s3:cmp ax,bx
mov z,1
jmp last
last:mov ax,4c00H
int 21H
code ends
end start
持续更新中~~