实验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行,卡了半天才想明白
posted @ 2021-11-23 23:07  439qi  阅读(46)  评论(0编辑  收藏  举报