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

執行截圖:

回答問題1


loop指令對應的機器碼是(E2F2)16,其中(F2)16是補碼錶示的偏移量,換算成十進位制數是-14。當前loop指令的長度是2位元組,下一條指令的偏移地址是(001B)16,減去(14)10剛好是標號s1對應的偏移地址(000D)16.

回答問題2

與問題1相似,機器碼中偏移量的補碼是(F0)16,對應十進位制-16。下一條指令的偏移地址是(0039)16,減(16)10得標號s2的偏移地址(0029)16.

實驗任務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中是標號s1的偏移地址,bx中是標號s2的偏移地址,cx中是標號s2的段地址。

注意到兩條call指令一個是短轉移一個是遠轉移。執行第一個call時,將當前命令的下一條命令的偏移地址(IP)壓入棧,也就是將標號s1的偏移地址壓入棧;隨後(IP)變為記憶體單元偏移地址為0的字單元中的數值,由於程式已經將該字單元賦值為標號s1的偏移地址,所以程式看起來就是順序執行了下面的命令而沒有進行跳轉,將剛剛壓入棧的偏移地址彈出給暫存器ax;執行第二條遠轉移call時,依次將下一條指令的段地址(CS)和偏移地址(IP)壓入棧,後面的過程與之前類似。

實驗截圖:

實驗任務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, 0
    mov cx, len
    s:
    mov ah, 0
    mov al, [si]
    inc si
    call printNumber
    call printSpace
    loop s

    mov ah, 4ch
    int 21h

printNumber:
    mov bl, 10
    div bl
    mov bx, ax
    mov ah, 2
    add bl, 48
    mov dl, bl  ;商
    int 21h

    add bh, 48
    mov dl, bh  ;餘數
    int 21h
    ret

printSpace:
    mov ah, 2
    mov dl, 32 ;空格的ASCII碼	
    int 21h
    ret

code ends
end start

測試截圖:

實驗任務4

源程式程式碼:

assume cs:code, ds:data

data segment
    str db 'try'
    len equ $ - str
data ends

stack segment
    db 16 dup(0)
stack ends

code segment 
start: 
    mov ax, stack
    mov ss, ax
    mov sp, 16

    mov ax, data
    mov ds, ax
    mov si, 0     ;資料段偏移地址
    mov cx, len   ;字串長度
    mov bh, 0     ;行號
    mov bl, 02h   ;黑底綠字
    call printStr 

    mov si, 0
    mov cx, len
    mov bh, 24
    mov bl, 04h   ;黑底紅字
    call printStr

    mov ah, 4ch
    int 21h

printStr:
    mov ax, 0b800h
    mov es, ax
    push bx        ;暫存顏色
    mov bl, bh
    mov bh, 0      ;bx中現在是行號(0-24)
    mov ax, 00a0h  ;一行的位元組數
    mul bx
    mov bx, ax     ;bx得到行首偏移地址
    pop ax
    mov ah, al

    s:
    mov al, [si]
    mov es:[bx+si], ax
    inc bx
    inc si
    loop s
    ret

code ends
end start

測試截圖:

實驗任務5

程式原始碼:

assume cs:code, ds:data

data segment
    stu_no db '201983290485'
    len = $ - stu_no
data ends

code segment
start:
    mov ax, data
    mov ds, ax
    mov ax, 0b800h
    mov es, ax
    mov si, 1
    mov cx, 7d0h    ;2000次迴圈
    s:
    mov byte ptr es:[si],17h    ;00010111
    add si, 2
    loop s
 
    mov si, 0f00h
    mov cx, 80
    s1:
    mov byte ptr es:[si], 2dh  ;-----
    add si, 2
    loop s1

    mov si, 0f44h   ;最後一行中間
    mov cx, 12
    mov bx, 0
    s2:
    mov al, [bx]
    mov es:[si], al
    add si, 2
    inc bx
    loop s2

    mov ax, 4c00h
    int 21h 

code ends
end start

測試截圖: