一、第一個彙編程序
例如:編寫一個彙編程序實現:x=4,y=5,z=((x+y)*8-x)/2,計算出z的結果。
思路
- 公式中出現的三個變量X、Y、Z是帶符號數,在數據段中定義
- 用算術運算指令實現加減運算
- 將操作數左移3位二進制位數代替乘以8運算,操作數右移1位相當於除以2
- 編寫程序的順序爲運算順序
DATA SEGMENT ;數據段定義僞指令
X DW 4 ;定義X爲字單元,值爲4
Y DW 5
Z DW ? ;定義Z爲空單元
DATA ENDS ;數據段結束
CODE SEGMENT ;代碼段定義僞指令
ASSUME CS:CODE,DS:DATA ;指定段寄存器與對應段名
START:MOV AX,DATA
MOV DS,AX ;將數據段段地址送入DS
MOV BX, X
MOV AX, Y
ADD AX,BX ;加法
MOV CL,3
SAL AX,CL ;算術左移3次,相當於乘以8
SUB AX,X ; 減法
SAR AX,1 ; 算術右移1次,相當於除以2
MOV AH,4CH ; 此兩句爲結束程序,返回DOS
INT 21H
CODE ENDS ; 代碼段結束
END START ; 整個程序結束僞指令
二、僞指令
類型參數 :
- PARA : 該段的起始地址必須爲小段的首地址,即段地址的十六進制數最低位爲0
- BYTE :該段可以從任意地址開始
- WORD : 該段必須從字邊界開始,即段的起始地址爲偶數
- DWORD :該段必須從雙字邊界開始,即段地址的十六進制數最低位應爲4的倍數
- PAGE :該段必須從頁邊界開始,即段地址的十六進制數最低兩位爲00(能被256整除)
如果不指出定位類型,系統默認爲PARA。
組合類型:
- PRIVATE : 該段爲私有段,連接時不與其他同名段合併
- PUBLIC :連接時可與其他模塊中的同名段按順序連接成一個段
- COMMON : 表示該段與其他模塊中的同名段有相同的起始地址,如果連接將產生覆蓋;連接後,段的長度爲同名段中的最長者
- STACK : 表示該段爲堆棧段
- AT 表達式 : 該段直接定位在表達式指出的位置上
如果不指定組合類型,系統默認爲PRIVATE。
在引號中給出段的類型名,在連接時,類別標識相同的段放在連續的存儲區中。例如,用‘STACK’來標識該段爲堆棧段 。
ASSUME僞指令
ASSUME僞指令用於指明段寄存器與段的對應關係,格式爲:
ASSUME段寄存器:段名,[段寄存器:段名,…]
如果不使用ASSUME僞指令,系統就無法獲知用戶定義的段都有哪些,進而就不能正確地劃分段。
數據定義僞指令
- DB 定義字節單元
- DW 定義字單元
- DD 定義雙字單元
- DQ 定義四字單元
- DT 定義十字節單元
存儲單元名 [定義] 操作數
確定存儲單元的內容時要與存儲單元的屬性一致。
在實際的存儲器中,符號地址(即變量名)已經不存在了,換之以偏移地址,而且最先定義的單元的偏移地址爲0000H。此例中,X單元的偏移地0000H,E_1單元的偏移地址爲0001H,其他類推。
其他僞指令
1.賦值僞指令
在程序中多次出現同一個表達式或者同一個數據時,可以用EQU定義-個符號來代表表達式,以簡化書寫。與EQU僞操作相似,等號“=”僞操作也可以給表達式賦值,且允許對一個符號多次重複定義。而EQU則不允許重複定義。
- name EQU expression
- name EQU symbol
- name EQU < >
第一種格式中,expression 必須是一個有效整數表達式。第二種格式中,symbol 是一個已存在的符號名稱,已經用 = 或 EQU 定義過了。第三種格式中,任何文本都可以岀現在<…>內。當彙編器在程序後面遇到 name 時,它就用整數值或文本來代替符號。
2.模塊定義僞指令
在彙編語言中,可以將程序設爲多個模塊,每個模塊完成獨立的功能,整個程序可以用LINK連接到一起。因此,每個模塊可用模塊定義僞指令定義名稱和結束標識。格式爲:
[NAME模塊名]
…
END 啓示標號
其中,NAME僞指令可以缺省。如果缺省,則以該模塊的源程序名作爲模塊名。END 僞指令不能缺省,其後的起始標號可以是程序的第-條彙編指令的標號START,或者是主過程名。它們用來指出程序的起始地址,也是對代碼段寄存器CS初始化的依據。
3.地址計數器$
地址計數器$表示當前的偏移地址值。
如果在數據段的存儲單元定義中使用,可寫成:
ABC DW 1,2,$+3,4
如果用在轉移指令中:
JMP $+5
則無條件跳轉到當前指令的偏移地址+5單元繼續執行。
4.設置偏移地址僞指令
當前的偏移地址可以用ORG僞指令定義。
如果用在數據段中,該指令可以確定存儲單元的偏移地址。例如,將X單元的偏移地址定義爲0020H,該單元的內容爲5,即(DS: 0020H) =5。僞指令如下:
DATA SEGMENT
ORG 0020H
X DW 5
DATA ENDS
如果用在代碼段中,可從指定的單元開始存放並執行指令。例如,從代碼段的100H開始執行:
ORG 100H
SIGN:MOV AX,X ;標號SIGN被設置爲100H
MOV BX,Y
ADD AX,BX
5.操作符
在彙編指令中可以使用–些操作符,彙編程序彙編時將這些操作符變爲相應的數值回送或者定義屬性.
二、屏幕顯示,鍵盤輸入
DOS功能調用
常用的DOS功能有5個:
- 鍵盤輸入1個字符: 01號DOS功能調用
- 顯示器輸出1個字符: 02號DOS功能調用
- 鍵盤輸入緩衝區: 0AH號DOS功能調用
- 顯示字符串: 09號DOS功能調用
- 返回DOS控制: 4CH號DOS功能調用
單字符的輸入輸出
- 1號功能鍵盤輸入
格式:
AH=1
INT 21H
從鍵盤輸入一個字符並將該字符的ASCⅡ碼送入AL中
- 2號功能顯示器輸出
格式:
AH=2
DL=字符
INT 21H
輸出DL中的一個字符到顯示器的光標處。
例如:鍵盤輸入的大寫字母換成小寫字母顯示
CODE SEGMENT
ASSUME CS:CODE ;段寄存器的說明語句,定義code爲代碼段
START:
MOV AH,1 ;輸入
INT 21H
SUB AL,32 ;轉換
MOV DL,AL
MOV AH,2
INT 21H
MOV AH,4CH
INT 21H ;結束程序返回DOS
CODE ENDS
END START
字符串的輸入輸出
鍵盤輸入字符串
格式:
AH=10
DS:DX=字節緩衝區首址
INT 21H
定義緩衝區的第1個字節單元爲允許輸入的最大字符數,第2個單元爲實際鍵入個數(由系統自動填入),從第3個單元開始存放鍵入字符。從鍵盤輸入一串ASCII字符到緩衝區,用“回車”結束輸入。若輸入字符超過緩衝區能容納的個數,則系統忽略此字符並響鈴警告。
顯示字符串
格式:
AH=9
DS:DX=字符串地址
INT 21H
顯示一個以$結尾的字符串,執行後AL寄存器被修改爲 $ 的ASCLL碼24H
例如:顯示出兩個字符串:
data segment
mess1 db 'input x :','$' ;$字符串結束符
mess2 db 0ah,0dh,'out put','$' ;0ah,0dh,換行回車
data ends
code segment
assume cs:code,ds:data
start : mov ax,data ;將僞段地址放入ax中
mov ds,ax ;就是將段地址裝入段寄存器
mov dx,offset mess1 ;回送偏移地址
mov ah,9
int 21h
mov dx,offset mess2
mov ah,9
int 21h
mov ah,4ch
int 21h
code ends
end start
參考書籍:《彙編語言》第二版 鄭曉薇
下篇重點總結各種基本彙編指令,鏈接。