【汇编实验】实验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其后指令的偏移地址的。
IP从001B跳转到000D,偏移量是-14
回答问题② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s2其后指令的偏移地址的。
IP从0039跳转到0029,偏移量是-16
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) = ?
由程序第十六行到底十八号可知,ds:[0]中存放的是s1的偏移地址,ds:[1]中存放s2的偏移地址,ds:[4]中存放数据段的段地址。在24行由于要执行call指令把偏移地址压入栈,所以把ds:[0]中存放的字数据也就是s1的偏移地址保存下来,所以ax中存放的是s1的偏移地址。在27行要把ds:[2]的双字数据保存下来,也就是ds:[2]和ds:[4]的,所以bx中的是s2的偏移地址,cx中存放的是数据段的段地址。
即ax = s1的ip,bx = s2的ip,cx = s2的cs
② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试 结果与理论分析结果是否一致。
可以发现 ax = 4c21, bx = 0026, cx = 076c
3. 实验任务3
这部分实验主要是将两位数分开十位和个位然后将两部分都转换为ASCII码再使用int21h的二号子程序将其输出即可
给出程序源码task3.asm
1 assume cs:code, ds:data 2 3 data segment 4 x db 99, 72, 85, 63, 89, 97, 55 5 len equ $- x 6 data ends 7 8 code segment 9 start: 10 mov ax, data 11 mov ds, ax; 12 mov si, 0 13 mov cx, len ;数据为byte,len即为数据长度 14 s: 15 mov ah, 0 ;数字只有一个字节所以ah=0 16 mov al, [si] 17 mov bx, offset printNumber 18 call bx 19 mov bx, offset printSpace 20 call bx 21 inc si 22 loop s 23 mov ah, 4ch 24 int 21h 25 26 printNumber: 27 mov bl, 10 28 div bl;分离十位和个位 29 mov bx, ax 30 31 mov dl, bl ;取商 32 add dl, 30h ;转换成ascii 33 mov ah, 2 ;调用int 21h的二号子程序 34 int 21h; 35 36 mov dl, bh ;取余数 37 add dl, 30h ;转换成ascii 38 mov ah, 2 ;调用int 21h的二号子程序 39 int 21h; 40 ret 41 42 printSpace: 43 mov dl, ' ' 44 mov ah, 2 45 int 21h 46 ret 47 48 code ends 49 end start
运行测试截图
4. 实验任务4
给出程序源码task4.asm
1 assume ds:data, cs:code 2 data segment 3 str db 'try' 4 len equ $ - str 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov ax, 0b800h 12 mov es, ax 13 mov si, 0 14 mov dh, 0 ;行号 15 mov bl, 2 ;颜色 16 call printStr 17 18 mov si, 0 19 mov dh, 24 ;行号 20 mov bl, 4 ;颜色 21 call printStr 22 mov ax, 4c00h 23 int 21h 24 25 printStr: 26 mov al, 160 ;一行可以存80个字符160个字节 27 mul dh 28 mov dx, ax ;相对寻址只能用bx, bp, si, di 29 mov al, bl 30 mov bx, dx 31 mov cx, len 32 s: 33 mov dl, [si] 34 mov es:[bx], dl 35 inc bx 36 mov es:[bx], al 37 inc bx 38 inc si 39 loop s 40 ret 41 code ends 42 end start
运行测试截图
5. 实验任务5
给出程序源码task5.asm
1 assume cs:code, ds:data 2 data segment 3 stu_no db '201983440007' 4 len = $ - stu_no 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov ax, 0b800h 12 mov es, ax 13 ;调背景色 14 mov si, 1 15 mov dl, 17h ; 0 001 0 111 16 mov cx, 2000 17 blue: 18 mov es:[si], dl 19 add si, 2 20 loop blue 21 ;打印横线 22 mov dh, 24 23 mov al ,160 24 mul dh ;计算起始位置 25 mov bx, ax 26 call line 27 28 mov cx, len 29 mov si, 0 30 sn: 31 mov dl, ds:[si] 32 mov es:[bx], dl 33 inc si 34 add bx, 2 35 loop sn 36 37 call line 38 mov ax, 4c00h 39 int 21h 40 41 line: 42 mov dl, '-' 43 mov cx, 34 ;( 80- 12 ) / 2 44 s: 45 mov es:[bx], dl 46 add bx, 2 47 loop s 48 ret 49 code ends 50 end start
运行测试截图