1. 实验任务1
task1.asm源码
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
运行截图
① line27, 汇编指令 loop s1 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机 器码,分析其跳转的位移量是多少?
(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s1其后指令的偏移地址的。
答:反汇编,查看机器码,loop s1对应的机器码为E2F2,E2代表loop,F2即为位移量,转化为2进制即1111 0010,此为补码,原码为1000 1110,即十进制数-14,故位移量为-14,001B即27-14=13,即000D,证实位移量是-14。
从cpu角度,ip开始为0019即25,执行完loop这条指令后+2,即为001B即27,进行位移-14,即27+(-14)=13即001D,ip为001D,即在s1标号处。
② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机 器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s2其后指令的偏移地址的。
答:反汇编,查看机器码,loop s2对应的机器码为E2F0,E2代表loop,F0即为位移量,转化为2进制即1111 0000,此为补码,原码为1001 0000,即十进制数-16,故位移量为-16,0039即57-16=41,即0029,证实位移量是-16。
从cpu角度,ip开始为0037即55,执行完loop这条指令后+2,即为0039即57,进行位移-16,即57+(-16)=41即0029,ip为0029,即在s2标号处。
③ 附上上述分析时,在debug中进行调试观察的反汇编截图
2. 实验任务2
程序task2.asm源码
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
给出分析、调试、验证后,寄存器(ax) = ? (bx) = ? (cx) = ? 附上调试结果界面截图。
① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = ? 寄存器(bx) = ? 寄存器(cx) = ?
ax即为s1的偏移地址0021,bx即为s2的偏移地址0026,cx即为cs即076C。
分析;当执行call word ptr ds:[0]时,ip为下一条指令的起始地址,即ip为s1代码段的起始地址。此时,先将cs压入栈中,再将ip=0021压入栈中。随后指令跳转到ds:[0]存放的地址,即s1标号处,此时执行出栈操作,将栈中的0021赋值给ax。所以ax的值就是s1的偏移地址。栈中此时剩下一个当前cs的值。
当执行call word ptr ds:[2]时,ip同样为下一条指令的起始地址,即ip为s2代码段的起始地址。此时,先将cs压入栈中,再将ip=0026压入栈中。随后指令跳转到ds:[2]存放的地址,即s2标号处,此时执行出栈操作,将栈中的0026赋值给bx。所以bx的值就是s2的偏移地址。栈中此时剩下两个当前cs的值。
这时,再进行出栈操作,就会将当前cs的值赋值给cx,故cx存放的是当前cs。
② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试 结果与理论分析结果是否一致。
答:调试结果与理论分析结果一致。
3. 实验任务3
程序源码task3.asm
assume cs:code, ds:data
data segment
x db 99, 72, 85, 63, 89, 97, 55
len equ $- x
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov cx,len
mov si,offset x
s:
mov al,[si]
mov ah,0
call printNumber
call printSpace
inc si
loop s
mov ah,4ch
int 21h
printNumber:
mov dl,10
div dl
mov bx,ax
mov dl,bl
or dl,30h
mov ah,2
int 21h
mov ah,2
mov dl,bh
or dl,30h
int 21h
ret
printSpace:
mov dl,' '
mov ah,2
int 21h
ret
code ends
end start
运行测试截图
4. 实验任务4
程序源码task4.asm
assume cs:code,ds:data data segment str db 'try' len equ $ - str data ends stack segment db 16 dup(0) stack 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,2 mov bh,0 call printStr mov si,offset str mov cx,len mov bl,4 mov bh,24 call printStr mov ah,4ch int 21h printStr: push bx mov al,bh mov bl,160 mul bl mov di,ax pop bx s: mov al,[si] mov es:[di],al mov es:[di+1],bl inc si add di,2 loop s ret code ends end start
运行测试截图
5. 实验任务5
程序源码task5
assume cs:code,ds:data data segment stu_no db '201983290262' len = $ - stu_no len1 equ 40-len/2; data ends stack segment db 16 dup(0) stack ends code segment start: mov ax,data mov ds,ax mov ax,0b800h mov es,ax mov bl,17 call setBackground mov bl,23 call printstuno mov ah,4ch int 21h setBackground: mov di,0 mov ax,0 mov al,25 mov dx,0 mov dl,80 mul dl mov cx,ax mov al,20h s: mov es:[di],al inc di mov es:[di],bl inc di loop s ret printstuno: mov ax,0b800h mov es,ax mov ax,0 mov al,24 mov dx,0 mov dl,160 mul dl mov di,ax mov cx,len1 s1: mov byte ptr es:[di],'-' mov es:[di+1],bl add di,2 loop s1 mov si,0 mov cx,len s2: mov al,ds:[si] mov es:[di],al mov es:[di+1],bl inc si add di,2 loop s2 mov cx,len1 s3: mov byte ptr es:[di],'-' mov es:[di+1],bl add di,2 loop s3 code ends end start
运行测试截图
实验总结(选)
1.汇编时出现问题operand must have size时,将对应报错语句明确传输的内容为word或者是byte,即明确大小,可以通过汇编。
2.or 寄存器,30h,表示将此寄存器的内容转换成对应的ascall码,因为2号功能调用dl内容以显示字符时,必须是ascaII码。