實驗3 轉移指令跳轉原理及其簡單應用程式設計

木回發表於2021-11-28

1. 實驗任務1

assume cs:code, ds:data
data segment
x db 1, 9, 3
len1 equ $ - x ; 符號常量, $指下一個資料項的偏移地址,這個示例中,是3
y dw 1, 9, 3
len2 equ $ - y ; 符號常量, $指下一個資料項的偏移地址,這個示例中,是9
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, offset x ; 取符號x對應的偏移地址0 -> si
mov cx, len1 ; 從符號x開始的連續位元組資料項個數 -> cx
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 ; 取符號y對應的偏移地址3 -> si
mov cx, len2/2 ; 從符號y開始的連續字資料項個數 -> cx
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其後指令的偏移地址的。

 

 

 F2H=[11110010]補=[10001110]原=-14O

-14O=(D-19-2)H

② line44,彙編指令 loop s2 跳轉時,是根據位移量跳轉的。通過debug反彙編,檢視其機器碼, 分析其跳轉的位移量是多少?(位移量數值以十進位制數值回答)從CPU的角度,說明是如何計算得 到跳轉後標號s2其後指令的偏移地址的。

 

 

 F0H=[11110000]補=[10010000]原=-16O

-16O=[29-37-2]H

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) = ? 暫存器 (bx) = ? 暫存器(cx) = ?

 

 

 

 

 

 

ax=0021

執行call word ptr ds:[0]時,先把當前的IP存起來,當前IP指向下一條命令,地址為0021,於是0021入棧

接著執行POP AX,將棧頂的內容彈出,儲存至AX,於是AX的值就是0021

bx=0026

執行call dword ptr ds:[2]時,因為dword(雙字),IP指向下一條指令的地址為076C:0026.於是0026先入棧,然後076C再入棧

接著執行POP BX,將棧頂的內容彈出,儲存至BX,棧頂為0026,於是BX的值就是0026

cx=076C

接著執行POP CX,將棧頂的內容彈出,儲存至CX,棧頂為076C,於是CX的值就是076C

3. 實驗任務3

編寫8086彙編源程式task3.asm,在螢幕上以十進位制形式輸出data段中這一組連續的資料,資料和資料 之間以空格間隔。 要求: 編寫子程式printNumber 功能:以十進位制形式輸出一個兩位數 入口引數:暫存器ax(待輸出的資料 --> ax) 出口引數:無 編寫子程式printSpace 功能:列印一個空格 入口引數:無 出口引數:無 在主體程式碼中,綜合應用定址方式和迴圈,呼叫printNumber和printSpace, 實現題目要求。

assume cs:code, ds:data

data segment
        x db 99, 72, 85, 63, 89, 97, 55
        len equ $ - x
data ends

code segment
main:   mov ax, data
        mov ds, ax

        mov si, offset x
        mov cx, len
s1:     mov ah, 0
        mov al, [si]
        call printNumber   ;輸出十進位制數字
        call printSpace      ;輸出空格

        inc si
        loop s1

        mov ax, 4c00h    
        int 21h

printNumber:

        mov bl, 10
        div bl            ;將兩位數分開來輸出,先模10,獲得十位數,al放商,ah放餘數,預設除數為ax
        mov bx, ax
        mov dl, bl
        or dl, 30h      ;將數字轉變成字元
        mov ah, 2     ;顯示字元(商)
        int 21h

        mov dl, bh
        or dl, 30h
        mov ah, 2       ; ;顯示字元(餘數)
        int 21h
        ret

printSpace:
        mov dl, ' '
        mov ah, 2
        int 21h
        ret

code ends
end main

  

 

 

 

 4. 實驗任務4

編寫子程式printStr 功能:在指定行、以指定顏色,在螢幕上顯示字串 入口引數 字串首字元地址 --> ds:si(其中,字串所在段的段地址—> ds, 字串起始地址的偏 移地址—> si) 字串長度 --> cx 字串顏色 --> bl 指定行 --> bh (取值:0 ~24) 出口引數:無 ; 功能:輸出單個字元 mov ah, 2 mov dl, ×× ; ××是待輸出的字元,或其ASCⅡ碼值 int 21h 1 2 3 4 5 data segment str db 'try' len equ $ - str data ends 1 2 3 4 在主體程式碼中,兩次呼叫printStr,使得在螢幕最上方以黑底綠字顯示字串,在螢幕最下方以黑 底紅色顯示字串

assume ds:data, cs:code

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

code segment
start:
    mov ax,data
    mov ds,ax

    mov si,0
    mov cx,len;字串長度為len賦值給cx
    mov bh,0  ;綠色字元顯示在第0行
    mov bl,02h;綠色
    call printStr

    mov si,0
    mov cx,len;字串長度為len賦值給cx
    mov bh,24   ;紅色字元顯示在第24行
    mov bl,04h;紅色
    call printStr

    mov ax,4c00h
    int 21h

    printStr:
    mov ax,0b800h  ;80*25字元緩衝區
    mov es,ax

    mov al,bh
    mov bh,0a0h   ;一行是160個位元組,即a0h總共偏移24行,即偏移地址為24*160個位元組
    mul bh             ;mul預設al和mul後面的暫存器相乘,結果放在ax中
    mov bp,ax
    s:
    mov ah,ds:[si];每次取出一個位元組給ah
    mov es:[bp],ah;把字母存給視訊記憶體地址低八位中
    inc bp
    mov es:[bp],bl;將顏色資訊存入高八位
    inc bp
    inc si
    loop s
    ret

code ends
end start

  

 

 

 5. 實驗任務5

在80×25彩色字元模式下,在螢幕最後一行正中間顯示學號。要求輸出視窗藍底,學號和兩側折線,以 白色前景色顯示。 注*: 1. 80×25彩色字元模式顯示緩衝區結構,參見教材「實驗9 根據材料程式設計」裡的說明。 2. 編寫程式實現時,將data段的學號換成自己的學號。

 assume ds:data, cs:code

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

code segment
start:
    mov ax,data
    mov ds,ax

    mov si,0
    mov cx,07D0h;
    mov bh,0
    mov bl,00010111B ;對應藍底白字
    call printblankspace
    mov si,0
    mov cx,004Fh;
    mov bh,24             ;字元顯示在第24行
    mov bl,00010111B;對應藍底白字
    call printline
    mov si,0
    mov cx,len             ;字串長度為len賦值給cx
    mov bh,24             ;綠色字元顯示在第24行
    mov bl,00010111B;對應藍底白字
    call printstr


    mov ax,4c00h
    int 21h


    printstr:
    mov ax,0b800h  ;80*25字元緩衝區
    mov es,ax

    mov al,bh
    mov bh,0a0h   ;一行是160個位元組,即a0.總共偏移24行,即24*160個位元組
    mul bh             ;mul預設al和mul後面的暫存器相乘,結果放在ax中
    add ax,3ch
    mov bp,ax        ;160/2-12/2=74
    s:
    mov ah,ds:[si];每次取出一個位元組給ah
    mov es:[bp],ah;把字母存給視訊記憶體地址低八位中
    inc bp
    mov es:[bp],bl;將顏色資訊存入高八位
    inc bp
    inc si
    loop s
    ret

    printline:
    mov ax,0b800h  ;80*25字元緩衝區
    mov es,ax

    mov al,bh
    mov bh,0a0h   ;一行是160個位元組,即a0.總共偏移24行,即24*160個位元組
    mul bh
    mov bp,ax
    s1:
    mov ah,'-';每次取出一個位元組給ah
    mov es:[bp],ah;把字母存給視訊記憶體地址低八位中
    inc bp
    mov es:[bp],bl;將顏色資訊存入高八位
    inc bp
    inc si
    loop s1
    ret

    printblankspace:
    mov ax,0b800h  ;80*25字元緩衝區
    mov es,ax

    mov al,bh
    mov bh,0a0h   ;一行是160個位元組,即a0.總共偏移24行,即24*160個位元組
    mul bh             ;mul預設al和mul後面的暫存器相乘,結果放在ax中
    mov bp,ax        ;bp為顯示字串開始的位置
    s2:
    mov ah,' '         ;每次取出一個位元組給ah
    mov es:[bp],ah;把字母存給視訊記憶體地址低八位中
    inc bp
    mov es:[bp],bl ;將顏色資訊存入高八位
    inc bp
    inc si
    loop s2
    ret



code ends
end start

 

 

相關文章