实验 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 其后指令的偏移地址的。- 运行到
loop s1
时指令指针寄存器指向其下一条指令的地址CS:IP = 076D:001B
- 该指令为段内段转移 E2F2 中后 8 bit(2 byte)
F2
为偏移量与 IP 进行补码运算得到新的 IP:IP: 1B (0001 1001) + F2 (1111 0010) = 0D (0000 1101)
- 运行到
-
回答问题 ②
② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过 debug 反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从 CPU 的角度,说明是如何计算得到跳转后标号 s2 其后指令的偏移地址的。-
与问题 ① 相同,计算过程:
IP: 39 (0011 0111) + F0 (1111 0000) = 29 (0010 0111)
-
- 问题 ③
③ 附上上述分析时,在 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) = IP 寄存器(bx) = IP 寄存器(cx) = CS
-
② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试
(ax) = IP = 0021
(bx) = IP = 0026
(cx) = CS = 076E
3. 实验任务 3
-
程序源码task3.asm
assume cs:code, ds:data data segment x db 99, 72, 85, 63, 89, 97, 55 len equ $ - x ; $(current address) data ends code segment ; print number in ax (0 <= [ax] <= 99) to console ; param : ax ; return : none printNumber: mov bl, 10 div bl mov bx, ax mov dl, bl add dl, 30h mov ah, 02h int 21h mov dl, bh add dl, 30h mov ah, 02h int 21h ret ; print a space to console ; param : none ; return : none printSpace: mov dl, 20h mov ah, 02h int 21h ret main: mov ax, data mov ds, ax mov cx, len mov di, 0 s: mov al, [di] mov ah, 0 call printNumber call printSpace inc di loop s mov ax, 4c00h int 21h code ends end main
-
运行测试截图
4. 实验任务 4
-
给出程序源码task4.asm
assume cs:code, ds:data data segment string db 'try' len equ $ - string data ends code segment ; param : si(string address), ; cx(string len), ; bl(string color), ; bh(string row) ; return : none printStr: mov ax, 0b800h ; screen mov es, ax mov ah, 0 mov al, 160 ; one line = 160 bytes mul bh mov di, ax s: mov al, [si] mov ah, bl mov es:[di], ax inc si add di, 2 loop s ret ; use cls command to clean screen main: mov ax, data mov ds, ax mov si, offset string mov cx, len mov bh, 0 mov bl, 2 call printStr mov si, offset string mov cx, len mov bh, 24 mov bl, 4 call printStr mov ax, 4c00h int 21h code ends end main
-
运行测试截图
5. 实验任务 5
-
给出程序源码task5.asm
assume cs:code, ds:data data segment id db '201983290254' len equ $ - id data ends code segment ; use cls command to clean screen main: mov ax, data mov ds, ax mov ax, 0b800h mov es, ax mov ax, 80 mov dl, 24 mul dl mov cx, ax mov al, 0 mov ah, 00010000b mov si, 0 s1: mov es:[si], ax add si, 2 loop s1 mov cx, 80 sub cx, len sar cx, 1 mov al, '-' mov ah, 00010000b s2: mov es:[si], ax add si, 2 loop s2 mov cx, len mov bx, offset id s3: mov al, [bx] mov ah, 00010000b inc bx mov es:[si], ax add si, 2 loop s3 mov ax, 160 mov dl, 25 mul dl sub ax, si sar ax, 1 mov cx, ax mov al, '-' mov ah, 00010000b s4: mov es:[si], ax add si, 2 loop s4 mov ax, 4c00h int 21h code ends end main
-
运行测试截图