ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

实验3 转移指令跳转原理及其简单应用编程

2021-11-29 20:01:38  阅读:122  来源: 互联网

标签:code 编程 mov si 指令 偏移 跳转 ax data


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其后指令的偏移地址的。

 在该指令中,位移量为F2;由于其是补码形式,将其转为十进制数应为 -14 。

首先,该指令的偏移地址为0019,根据该指令的指令长度,CPU计算得到下一条指令的偏移地址为001B,然后用下一条指令的偏移地址减去位移量,就可得到跳转后的偏移地址000D。

 

② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码, 分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得 到跳转后标号s2其后指令的偏移地址的。

 在该指令中,位移量为F0;由于其是补码形式,将其转为十进制数应为 -16 。

首先,该指令的偏移地址为0037,根据该指令的指令长度,CPU计算得到下一条指令的偏移地址为0039,然后用下一条指令的偏移地址减去位移量,就可得到跳转后的偏移地址0029。

 

③ 附上上述分析时,在debug中进行调试观察的反汇编截图

 

    

 

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

 

给出分析、调试、验证后,寄存器(ax) = ? (bx) = ? (cx) = ? 附上调试结果界面截图。

执行call后会把当前地址的下一条指令地址隐式地存入栈中;

第一次call存入s1的偏移地址,并通过pop ax将该地址赋给给ax,所以ax=offset s1=0021h

第二次call依次存入s2的段地址和偏移地址,先通过pop bx弹出偏移地址,所以bx=offset s2=0026h;然后pop cx弹出段地址,所以cx=code=076c

ax=0021,bx=0026,cx=076c

 

 

 

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:    call printNum
    call  printSpace 
    inc si
    loop s
    
    mov ax,4c00h
    int 21h

printNum:     mov ah,0 ;高位置0
    mov al,[si] ;低位保存一字节数
    ;由于一次只能输出一个字符
    ;因此将十位数除10,先输出商在输出余数
    mov bl,10
    div bl
    mov bx,ax
    
    mov ah,2
    mov dl,bl ;低位保存的是商,即十位
    or dl,30h ;将数字转为字符,相当于加48
    int 21h
    mov ah,2
    mov dl,bh ;高位保存的是余数,即个位
    or dl,30h
    int 21h
    ret    

printSpace:    mov ah,2
    mov dl,32
    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 ax,0b800h ;es放显存
    mov es,ax
    mov cx,0

    mov bh,0  ;bh指定行
    mov bl,2h  ;bl字符串颜色,黑底绿字
    call printStr

    mov bh,24
    mov bl,4h ;黑底红字
    call printStr

    mov ax,4c00h
    int 21h

printStr:    mov si,offset str  ;字符串起始偏移地址
    mov cx,len ;字符串长度
    
    mov ah,0
    mov al,bh ;ax中保存指定行
    mov dx,160 ;每行160字节
    mul dx ;计算指定行的起始偏移地址
    mov di,ax ;mul 8位结果会放在ax中
    
    s:  mov al,[si] ;先放低位,低位存字符
         mov es:[di],al
         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 '201983290331'
    len = $ - stu_no
data ends
code segment
start:    mov ax,data
    mov ds,ax
    mov ax,0b800h ;es显存地址
    mov es,ax

    mov bx,1700h
    call printCol

    ;第25行开始偏移地址为3840
    ;24*80=1920 word =3840 byte
    mov si,3840
    mov cx,160 ;
    call printLine

    ;len=12
    mov si,3914 ;3840+(160-12)/2
    mov cx,12
    call printNum

    mov ax,4c00h
    int 21h

printCol:    mov si,0
    mov cx,4000 ;25*80*2 byte
    s:
    mov es:[si],bl
    mov es:[si+1],bh
    add si,2
    loop s
    ret


printLine:    
    mov bh,17h
    mov bl,2dh
    s1:
    mov es:[si],bl
    mov es:[si+1],bh
    add si,2
    loop s1
    ret

printNum:
    mov di,0
    s2:
    mov bl,[di]
    mov es:[si],bl
    mov es:[si+1],bh
    add si,2
    inc di
    loop s2
    ret

    
code ends
end start

运行结果:

 

标签:code,编程,mov,si,指令,偏移,跳转,ax,data
来源: https://www.cnblogs.com/2201589821sbc/p/15606686.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有