实验3 转移指令跳转原理及其简单应用编程
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其后指令的偏移地址的。
-14
Cpu执行E2F2,F2是十进制-14的补码,即ip向前移动14个字节到076B:000D处。
② line44,汇编指令跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得到跳转后标号s2其后指令的偏移地址的。
-16
Cpu执行E2F0,F0是十进制-16的补码,即ip向前移动16个字节到076B:000D处。
③ 附上上述分析时,在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
① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = ? 寄存器(bx) = ? 寄存器(cx) = ?
寄存器(ax) = 0021H寄存器 (bx) =0026H 寄存器(cx) =076CH
② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试 结果与理论分析结果是否一致。
call word ptr ds:[0]使ip入栈赋值给ax,因此AX中是0021H.
call dword ptr ds:[2]使cs,ip入栈,后将cs中的值赋给cx,ip赋给bx,因此bx中使0026,cx中是076C.
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 code segment start: mov ax, data mov ds, ax mov si, offset x mov cx, len s1: mov ah,0 mov al,[si] push ax call printNumber call printSpace pop ax inc si loop s1 mov ah, 4ch int 21h printNumber: mov bl,10 div bl mov bx,ax mov ah,2 or bl, 30h mov dl,bl int 21h or bh, 30h mov dl,bh int 21h ret printSpace: mov ah,2 mov dl, ' ' int 21h ret code ends end start
运行测试截图
实验要求输出的都是两位数,即被除以10后余数和商分别代表个位和十位,上述代码虽然能完成实验要求,但是如果是三位数及以上就不适用。这种情况就要增加循环,将每一次除得的余数压进栈,再一个个出栈完成输出。
4. 实验任务4
给出程序源码task4.asm
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 bl,2 ;属性 mov bh,0 ;行号 call printStr;输出绿色上方 mov si,offset str mov bl,4 mov bh,24 call printStr;输出红色下方 mov ah, 4ch int 21h printStr: mov al, bh mov dl, 0A0h mul dl ;计算偏移地址 mov di, ax mov cx,len s: mov al,[si] mov ah,bl mov es:[di],ax inc si add di,2 loop s ret code ends end start
运行测试截图
5. 实验任务5
给出程序源码task5.asm
assume cs:code, ds:data data segment stu_no db '201983290532' len = $ - stu_no data ends code segment start: mov ax, data mov ds, ax mov ax,0B800H mov es,ax mov cx,0780H mov ah,00010000b mov al,' ' mov bx,0 back: mov es:[bx],ax;输出蓝色底色 add bx,2 loop back mov cx,80 mov ah,00010111b mov al,'-' vet: mov es:[bx],ax;输出最后一排全部‘-’ add bx,2 loop vet mov cx,len mov bx,0F44H mov si,0 letter: mov al,[si];输出学号 mov es:[bx],ax inc si add bx,2 loop letter mov ah, 4ch int 21h code ends end start
运行测试截图
在输出学号时,是自己计算得到偏移地址为0f44h,如果更完整应该将25-1=24的行号乘以160个字符再加上[(80-12)/2]16得出偏移地址。