四、实验结论
1、实验任务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
运行截图
问题一:反汇编截图如下:
可以看到, loop s1 反汇编之后是 loop 000D 即是跳转的地址为000D,跳转是根据位移量跳转的,跳转规则为 当前IP+偏移量=跳转地址 ,当前IP为001B,转换成十进制是27,跳转地址是000D,转换成十进制是13,可以计算的到偏移量是 -14 。
从CPU角度,可以查看存储的内容,可以发现存储的内容是 F2 ,
转换成二进制为 1111 0010 ,而 -14 的补码为 1110 0010 ,刚好就是F2,所以CPU是把偏移量存储下来,再根据IP的值来计算偏移之后的指令地址的。
问题二:反汇编截图如下:
可以看到, loop s2 反汇编之后是 loop 0029 即是跳转的地址为0029,跳转是根据位移量跳转的,跳转规则为 当前IP+偏移量=跳转地址 ,当前IP为0039,转换成十进制是57,跳转地址是0029,转换成十进制是41,可以计算的到偏移量是 -16 。
从CPU角度,可以查看存储的内容,可以发现存储的内容是 F0 ,
转换成二进制是 1111 0000 ,而 -16 的补码为 1111 0000 ,刚好就是F0,所以CPU是把偏移量存储下来,再根据IP的值来计算偏移之后的指令地址的。
问题三:反汇编截图已经给出
2、实验任务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)理论分析,在程序退出之前,ax=21,bx=26,cx=076c。
(2)debug调试,验证,结果为
与理论分析结果一致
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, len s: mov ah, 0 mov al, [si] call printNumber call printSpace inc si loop s mov ah, 4ch int 21h printNumber: mov bx, 10 div bl mov bx, ax add bx, 3030h mov ah, 2 mov dl, bl int 21h mov ah, 2 mov dl, bh int 21h ret printSpace: mov ah, 2 mov dl, 20h 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 si, offset str mov cx, len mov bl, 0ah mov bh, 0 call printStr mov cx, len mov si, offset str mov bl, 0ch mov bh, 24 call printStr mov ah, 4ch int 21h printStr: mov al, 00a0h mul bh mov di, ax mov ax, 0b800h mov es, ax mov al, bl 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 cs:code, ds:data data segment stu_no db '201983290270' len =$ - stu_no data ends code segment start: mov ax, data mov ds, ax mov si, offset stu_no mov cx, len mov ax, 0b800h mov es, ax mov di, 0 mov al,24 mov dl, 80 mul dl mov cx, ax s: mov al, 17h mov es:[di], byte ptr 20h mov es:[di+1], al add di, 2 loop s mov ax, 80 sub ax, len mov dl, 2 div dl mov cx, 0 mov cl, al mov bx, cx call gang mov cx, len s2: mov al, ds:[si] mov ah, 17h mov es:[di], ax add di, 2 inc si loop s2 mov cx, bx call gang mov ah, 4ch int 21h gang: s1: mov al, '-' mov ah, 17h mov es:[di], ax add di, 2 loop s1 ret code ends end start
运行测试截图
实验结果与预期一致。
五、实验总结
通过本次实验,我掌握了跳转指令的使用、子程序的编写以及显示字符的方法,使用call指令与ret指令配合实现子程序的编写,窗口显示的有25行,80列。