幾個彙編入門小例子

Tattoo_Welkin發表於2018-05-16

一:列印 Hello World

DATA SEGMENT  
    BUF DB 'HELLO WORLD!  THIS IS MY FIRST ASM FILE! $'  
DATA ENDS  

CODE SEGMENT  
    ASSUME  CS:CODE,DS:DATA  
START:  
    MOV AX,DATA  
    MOV DS,AX  

    LEA DX,BUF  

    MOV AH,09H
    INT 21H  

    MOV AH,4CH  
    INT 21H  

CODE ENDS  
END START  

小記:

1. 字串的最後一個字元必須是“$”

2. LEA DX,BUF 等價於 MOV DX,OFFSET BUF

3.通過功能號為 9 的DOS功能呼叫實現字串的顯示

09H     顯示字串
01H     單個字元的輸入
02H     單個字元的輸出

二:計算 ffff:0 ~ ffff:b 單元中的資料的和,儲存在 dx 中。

分析:

1.運算結果是否會超出dx所能儲存的範圍?

答:dx ,一個字,有兩個位元組,16位 ,範圍在 0~65535 。ffff:0 ~ ffff:b**記憶體單元中的資料都是位元組型資料**,範圍在0~255之間,12個這樣的資料相加不會超過65535 ,所以完全可以存放的下!

;例項:計算ffff:0~ffff:b 單元 中的資料的和 ,儲存在dx中 。
assume cs:TT 
TT segment 
    start :
    mov ax,0ffffh
    mov ds,ax 

    mov dx,0  

    mov bx,0 

    mov cx,12 
tag:
    mov al,[bx]
    mov ah,0
    add dx,ax 
    inc bx 
    loop tag 

    mov ax,4c00h
    int 21h 

    TT ends  
end 

小記:

1. cx 用來控制 loop 迴圈次數

2. 位元組對應位元組 ,字對應字 。

    mov al,[bx]
    mov ah,0
    add dx,ax 

3.彙編中資料必須以0 開頭,即 0ffffh ,而不能是 ffffh

三:從鍵盤輸入兩個十進位制數 ,然後以十進位制數的形式輸出他們的和 。

分析:

1.鍵盤輸入得到他們的ASCII碼值 
2.減去30H,得到以非壓縮型BCD數形式表示的十進位制數字 
3.相加並進行調整(AAA )
4.再加上30H ,變為對應的ASCII碼值 ,輸出即可 

DATA SEGMENT  
    INFOR1 DB  "Please input the frist data(<10):$"
    INFOR2 DB  0AH,0DH,"Please input the second data(<10):$" 
    INFOR3 DB  0AH,0DH,"The result is:$ " 
DATA ENDS 

CODE SEGMENT  
    ASSUME CS:CODE ,DS:DATA 
START :
    MOV AX ,DATA
    MOV DS,AX

    MOV DX ,OFFSET INFOR1 ;顯示提示資訊 
    MOV AH,09H  
    INT 21H 

    MOV AH,01H ;接受輸入 
    INT 21H  ;此時等待使用者輸入,輸入的字元一定存放在AL中
    sub AL,30H 

    MOV BL,AL ;轉移到 BL 

    MOV DX ,OFFSET INFOR2 ;顯示提示資訊 
    MOV AH,09H 
    INT 21H

    MOV AH,01H  ;另一個數放在 AL 中
    INT 21H
    sub AL,30H  

    MOV DX ,OFFSET INFOR3
    MOV AH,09H 
    INT 21H 


    XOR AH,AH ; 清零 AH ,CF標誌位也會清零 
    add AL,BL  
    AAA  

    push AX 
    MOV  DL,AH 
    add DL,30H
    MOV AH,02H
    INT 21H

    pop AX 
    MOV DL,AL 
    add DL,30H 
    MOV AH,02H
    INT 21H

    MOV AX,4C00H
    INT 21H


    CODE ENDS
END START 

小記:

1. 從鍵盤輸入一個字元 (輸入的字元一定存放在AL中

    mov AH,01H ;接受輸入 
    int 21H  ;此時等待使用者輸入,輸入的字元一定存放在AL中
    sub AL,30H 

2. XOR XX,XX ; 清零 XX ,CF標誌位也會清零

3. 顯示一個字元( 顯示的一定是 DL中的內容 )

    mov AH,02H
    int 21H

4.因為在途中將有些單詞寫為小寫時出現了錯誤,所以建議全部寫為大些形式 ,保證不會出錯 !

5.關於push ax 和 pop ax 。 說實話 ,我還不是很懂,所以不敢亂說 ~_~

6.學習參考連結:(DOS功能呼叫一覽表)https://blog.csdn.net/icurious/article/details/51628343

四:將記憶體 ffff:0 ~ ffff:b 段元中的資料拷貝到 0:200 ~ 0:20b 單元中 , 0:200 ~ 0:20b 就等價於 0020:0 ~ 0020:b

ASSUME CS:TT 
TT SEGMENT 
START:
    MOV BX,0 

    MOV CX,12
s:  MOV AX,0FFFFH
    MOV DS,AX 
    MOV DL,[BX]

    MOV AX,0020H
    MOV DS,AX 
    MOV [BX],DL 
    INC BX 
    LOOP s

    MOV AX,4C00H
    INT 21H
TT ENDS 
END 

因為每次迴圈要設定兩次ds,效率會比較低下,所以我們來優化一下 :

ASSUME CS:TT 
TT SEGMENT 
START:

    MOV BX,0 
    MOV AX,0020H
    MOV ES,AX

    MOV AX,0FFFFH
    MOV DS,AX 

    MOV CX,12
s: 
    MOV DL,[BX]
    MOV ES:[BX],DL 
    INC BX 
    LOOP s

    MOV AX,4C00H
    INT 21H
TT ENDS 
END 

小記:

1. 因源單元和目標單元相距大於 64KB ,在不同的64KB段裡,程式中,每次迴圈要設定兩次ds

2. 使用段字首 MOV ES:[BX] , DL (其實也很簡單了)

3. 0:200h ~ 0:2FFh 共256個位元組的空間(幾乎不會被使用,什麼都不會存放) 可以作為一段安全的空間任意使用

五:將 data 資料段的資料通過棧的性質倒序存入

ASSUME CS:TT,DS:DATA,SS:STACK  

DATA SEGMENT  
    DW 0123H,0456H,0789H,0ABCH,0DEFH,0FEDH,0CBAH,0987H ;資料段原始資料
DATA ENDS 

STACK SEGMENT
    DW 0,0,0,0,0,0,0,0 
STACK ENDS 

TT SEGMENT 
START:       ; CS:IP pointer here 
    MOV AX,STACK 
    MOV SS,AX 
    MOV SP,16 ;棧頂指標指向 16(2*8) 

    MOV AX,DATA
    MOV DS,AX 

    MOV BX,0
    MOV CX,8 
tag:PUSH [BX]
    ADD  BX,2
    LOOP tag 

    MOV BX,0
    MOV CX,8
s:  POP [BX]
    ADD BX,2
    LOOP s

    MOV AX,4C00H
    INT 21H
    TT ENDS 
END START 

小記:

1.

 dw 即 define word  , 定義字型資料 
 db 即 define byte  , 定義位元組型資料 

2. DS,CS,SS,ES 不能直接給資料,必須通過通用暫存器(ax,bx,cx,dx )給他們賦值

比如: MOV DS,DATA     會出錯

3. sp 一次移動兩個單元(即一個字)

4.

    push指令 –> ①SP-2 –> ②將**字型資料**存放到SS:SP地址中 
    pop指令 –> ①將SS:SP地址的**字型**資料取出來 –> ②SP+2 

六:輸入年齡(如果是三位數就直接輸入即可,如果是兩位數,第三位數寫為0 。比如:032 ),輸出其所對應的年齡段名稱 。

分析:

1.得到三個數字字元
2.先判斷百位是不是 1,如果是1 ,在判斷十位大不大於5 ,
  大於5,其他物種,小於5,是個老人啊 
3.再判斷百位是不是0 ,如果不是,其他物種,如果是,判斷十位
    < 60 child  
    60~80 middle man 
    > 80 old man 

DATA    SEGMENT
        INFOR1  DB 0AH,0DH,"Please  input your age :$"
        INFOR2  DB 0AH,0DH,"Your age is < 60 ,I think you are a child $"
        INFOR3  DB 0AH,0DH,"You are a middle man $"
        INFOR4  DB 0AH,0DH,"You are  a  old man $"
        INFOR5  DB 0AH,0DH,"You are a  other species !$" 
        AGE     DB 0,0,0
DATA    ENDS

CODE    SEGMENT
      ASSUME CS:CODE,DS:DATA
START:  
        MOV  AX,DATA
        MOV  DS,AX

        MOV  DX,OFFSET INFOR1
        MOV  AH,09H
        INT 21H 

        MOV CX,3 
        MOV BX,OFFSET AGE 
    tag:
        MOV AH,01H  ;接受輸入 
        INT 21H    ;此時等待使用者輸入,輸入的 one ge 字元一定存放在 AL 中
        MOV [BX],AL  
        INC BX 
        LOOP tag 

        MOV BX,OFFSET AGE    
        CMP  [BX],BYTE PTR '1'
        JE   TEMP   ; == 1

        CMP BYTE PTR [BX],'0'
        JNE  OTHER  ; != 0 

        INC BX 
        CMP  [BX],BYTE PTR '6'
        JB CHILD 

        CMP  [BX],BYTE PTR'8'
        JB MAN 
        JNB OLD_MAN  

        JMP  PEND
    TEMP:
        INC BX
        CMP [BX],BYTE PTR'5'
        JNA OLD_MAN ; <= 5 
        JA OTHER   ; >5
    CHILD:
        MOV  DX,OFFSET INFOR2
        MOV  AH,09H
        INT 21H 
        JMP  PEND       ;注意執行完一個分支後應使程式跳出
    MAN:    
        MOV  DX,OFFSET INFOR3
        MOV  AH,09H
        INT 21H 
        JMP  PEND       

    OLD_MAN:    
        MOV  DX,OFFSET INFOR4 
        MOV  AH,09H
        INT 21H 
        JMP  PEND       

    OTHER:  
        MOV  DX,OFFSET INFOR5 
        MOV  AH,09H
        INT 21H 
        JMP  PEND       

    PEND:
        MOV  AH,4CH
        INT  21H
CODE    ENDS
END  START

這裡寫圖片描述

小記:

1.字與位元組必須對應

    CMP  [BX],BYTE PTR '1'
    JE   TEMP   ; == 1

2. 檢測比較結果的條件轉移指令( je 和 jz相同)

je/jz     等於則轉移         zf=1

jne/jnz    不等於則轉移     zf=0

jb     低於則轉移        cf=1

jnb    不低於則轉移    cf=0

ja     高於則轉移        cf=0且zf=0

jna    不高於則轉移    cf=1或zf=1

助記:

    e : equal

    ne : not equal

    b: below ;在下面,到下面,低於;(表示位置)在…下面 

    nb : not below

    a : above ;表示程度)超過;(表示等級)在…之上;(表示位置)在…正上

    na : not above

相關文章