实验3 转移指令跳转原理及其简单应用编程
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
运行截图
① line27, 汇编指令 loop s1 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得到跳转后标号s1其后指令的偏移地址的。
位移量为-14,计算公式为(offset s1)-(loop s1偏移地址)-2
② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机 器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s2其后指令的偏移地址的。
位移量为-16,计算公式为(offset s2)-(loop s2偏移地址)-2
③ 附上上述分析时,在debug中进行调试观察的反汇编截图
loop 000d对应的机器码E2F2,F2即为-14补码
loop 0029对应机器码为E2F0,F0即为-16补码
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
① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = offset s1 寄存器(bx) = offset s2 寄存器(cx) = cs
② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用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 mov bl,0ah s1: mov al,[si] mov ah,0 call printNumber call printSpace inc si loop s1 mov ah, 4ch int 21h printNumber: ;除10取模 div bl mov bh,ah mov dl,al ;转ASCII码 or dl,30h mov ah,2 int 21h mov dl,bh or dl,30h int 21h ret printSpace: mov ah,2 mov dl, ' ' 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 cx,len mov si,offset str mov bh,0 mov bl,2 call printStr mov cx,len mov si,offset str mov bh,24 mov bl,4 call printStr mov ah,4ch int 21h printStr: ;计算行对应段地址 mov al,0ah mul bh add ax,0b800h mov es,ax mov di,si ;写入显存 s: mov al,ds:[si] mov ah,bl mov es:[di],ax inc si add di,2 loop s ret code ends end start
5. 实验任务5
assume cs:code,ds:data data segment stu_no db '201983290521' len = $-stu_no data ends stack segment dw 2 dup(0) stack ends code segment start: ;蓝底白字 mov bl,00010111b mov bh,' ' mov ax,stack mov ss,ax mov sp,2 mov ax,data mov ds,ax mov si,0 mov cx,25 ;填充背景 fillBg: mov al,0ah mov dx,si mul dl add ax,0b800h mov es,ax push cx push si mov cx,050h mov si,1 ;内循环,填充一行 fillBgLine: mov es:[si],bx add si,2 loop fillBgLine pop si pop cx inc si loop fillBg ;处理最后一行 mov dx,028h sub dx,len/2 ;2dx为折线数 mov si,0 ;输出前折线 call printLine ;输出学号 mov cx,len mov di,offset stu_no no: mov al,ds:[di] mov es:[si],al inc di add si,2 loop no ;输出后折线 call printLine mov ah,4ch int 21h printLine: mov cx,dx s: mov es:[si],byte ptr '-' add si,2 loop s ret code ends end start
五、实验总结(选)
- 数字写入到显存显示要转换成对应字符,即ascii码
- 输入命令那一行到屏幕最下面一行时,输入命令后显存会上移一行,一开始第4题执行4.exe前没清屏每次输出总是差了1行,卡了半天才想明白