|
1.任务一
程序代码如下:
assume cs:code, ds:data
data segment
x db 1, 9, 3
len1 equ $ - x
y dw 1, 9, 3
len2 equ $ - y
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, offset x
mov cx, len1
mov ah, 2
s1:mov dl, [si]
or dl, 30h
int 21h
mov dl, ' '
int 21h
inc si
loop s1
mov ah, 2
mov dl, 0ah
int 21h
mov si, offset y
mov cx, len2/2
mov ah, 2
s2:mov dx, [si]
or dl, 30h
int 21h
mov dl, ' '
int 21h
add si, 2
loop s2
mov ah, 4ch
int 21h
code ends
end start
程序执行结果如下:
1.
EQU 伪指令把一个符号名称与一个整数表达式或一个任意文本连接起来;
“$” 是汇编语言中的一个预定义符号,等价于当前正汇编到的段的当前偏移值;
offset:取标号的偏移地址;
2.回答问题
(1)
loop处机器码为E2F2,指令实现的是段内短转移,范围是-128~127,后两位是位移量的补码形式,转换为二进制是11110010,
转换为原码为10001110,转化为十进制为-(2+4+8)=-14,即向前14个字节,loop处偏移量为0019H,转换为十进制是16+9=25,
又因为loop指令占2字节,所以读取完这条指令ip值自动+2,即为25+2=27;27-14=13为跳转到的指令的偏移地址,转换为16进制为
000D,发现正是s1标号处的偏移地址,跳转成功。
(2)
同上,loop指令机器码为E2F0,位移量补码11110000,原码10010000,十进制-16,当前指令读取完毕ip值变为0039,即9+16*3=57,57-16
=41=2*16+9,转化为16进制为0029,即为标号s2处偏移地址。
2.实验任务二
assume cs:code, ds:data
data segment
dw 200h, 0h, 230h, 0h
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov word ptr ds:[0], offset s1
mov word ptr ds:[2], offset s2
mov ds:[4], cs
mov ax, stack
mov ss, ax
mov sp, 16
call word ptr ds:[0]
s1: pop ax
call dword ptr ds:[2]
s2: pop bx
pop cx
mov ah, 4ch
int 21h
code ends
end start
(1)查阅资料可知:
call word ptr 内存单元地址,相当于push IP AND jmp word ptr 内存单元地址。
call dword ptr 内存单元地址,相当于push CS AND push IP AND jmp dword ptr 内存单元地址。
(ax)=offset s1;
call dword ptr ds:[2]执行后,栈依次弹出这条call指令的下一条指令的ip和cs;下一条指令的cs就为code段起始地址,ip为编号s2;
(bx)=offset s2;
(cx)=code
(2)结果如下:
可见执行完call指令后,ip下一条指令的偏移地址0021,即将0021压栈,pop ax后,ax为0021;
应当进栈的cs:ip为076c:0026,发现bx=0026,ip先出栈,cx=076c,cs再出栈。
3.实验任务3
assume cs:code, ds:data
data segment
x db 99, 72, 85, 63, 89, 97, 55
len equ $ - x
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, offset x ;第一个数据的偏移地址
mov cx, 7
mov byte ptr ds:[8],10
s: mov ah, 0
mov al, [si] ;被除数
div byte ptr ds:[8]
call printNumber
call printSpace
inc si ;db一个数据一字节,加一
loop s
mov ax, 4c00h
int 21h
printNumber:
mov bx, ax
or bh, 30h ;转为acsii码
or bl,30h
mov ah,2
mov dl,bl ;低位商
int 21h;
mov dl,bh ;高位余数
int 21h;
ret
printSpace:
mov ah, 2
mov dl, ' '
int 21h
ret
code ends
end start
结果如下:
4.实验任务4
assume cs:code, ds:data
data segment
str db 'try'
len equ $ - str
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, 0b800h
mov es, ax ;进入显存
mov si, offset str;第一个字符偏移地址
mov cx, len
mov bl, 2h ;颜色为绿色
mov bh, 0 ;行数为第0行
call printStr
mov si, offset str
mov cx, len
mov bl, 4h ;颜色为红色
mov bh, 24 ;行数为第24行
call printStr
mov ax, 4c00h
int 21h
printStr:
mov al, 160 ;一行80字符
mul bh
mov di, ax ;ax为第bh行的偏移量,行*列,从es:di开始输出字符
s: mov ah, ds:[si]
mov es:[di], ah ;字符
mov es:[di+1], bl ;颜色
add di, 2
inc si
loop s
ret
code ends
end start
结果如下:
5.实验任务5
代码如下:
assume ds:data, cs:code
data segment
stu_no db '201983290125'
len = $ - stu_no
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, 0b800h
mov es, ax
mov cx, 4000 ;每一屏字节数:80×25×2 = 4000字节
mov di, 0
mov ah,17h ;蓝底白字
s1: mov al, 0
mov es:[di], al;低字节字符
mov es:[di+1], ah;高字节颜色、闪烁
add di, 2
loop s1
;整个屏幕编程蓝底
;最后一行开始的-
mov di, 3840 ;第24行开始
mov cx, 34 ;一行160字节,显示字符串12*12=24字节,两边136/4=34,即2边各打印34个-
mov ah, 17h
s2: call printSign
add di, 2
loop s2
;打印学号
mov di, 3908 ;学号开始偏移地址
mov si, offset stu_no
mov cx, len;循环次数即学号位数
mov ah, 17h;蓝底白字
s3: call printStu
inc si
add di, 2
loop s3
;最后一行最后的-
mov di, 3932 ;=3840-68
mov cx, 34
mov ah, 17h
s4: call printSign
add di, 2
loop s4
mov ax, 4c00h
int 21h
printStu:
mov al, [si];学号数字
mov es:[di], al
mov es:[di+1], ah
ret
printSign:
mov al, 2Dh ;-
mov es:[di], al
mov es:[di + 1], ah
ret
code ends
end start
结果如下:
来源:https://www.cnblogs.com/nuistlyc/p/15606934.html |