【8086匯編基礎】03--變量、數組和常量的處理


8086匯編語言初學者教程(第三部分)

變量

變量是一個內存地址。對於編程者來說,使用諸如名稱為“var1”這樣的

變量保存數據遠遠比使用5a73:235b這樣的地址容易的多。特別是當你

使用10個以上的變量的時侯。

編譯器支持這兩種變量 BYTE  WORD.(字節和字)

聲明變量的方法:

name DB value 名稱 DB 值

name DW value 名稱 DW 值

DB - stays for Define Byte.
DW - stays for Define Word.

name -可以是任何字母與數字構成,但是必須由字母

開頭。可以通過不命名來聲明一個沒有名稱的的變量(這個變量

只有地址,沒有名稱)

value - 可以是任何數值支持三種進制(十六進制,二進制和

十進制),你可以使用"?"符號表示初始值沒有確定。


你可能從第二章了解到, MOV 指令是將數值從源拷貝到目的。

讓我們再看一個 MOV 指令的例子


#MAKE_COM#
ORG 100h

MOV AL, var1
MOV BX, var2

RET    ; stops the program.

VAR1 DB 7
var2 DW 1234h


將上面的代碼拷貝到emu8086源程序編輯器中,按下F5鍵編譯

並在模擬器中執行。你會看到如下畫面

 

從畫面可以看出,反編譯后的代碼同源程序很相似,不同的是變量

被具體的內存地址取代。當編譯器生成機器代碼它會自動將變量名稱

用該變量的便宜量代替。默認情況下,DS 寄存器存放段偏移

(當執行com文件的時侯,DS 寄存器的值同 CS 寄存器(代碼段)

的值一樣)。
 

內存第一列是偏移(offset),第二列是一個十六進制值

(hexadecimal value),第三列是十進制(decimal value)

最后一列是 ASCII 字符。


編譯器是非大小寫敏感的,所以 “VAR1” 同 “var1” 都是同一個變量。


VAR1變量的偏移是0108h,物理地址是0b56:0108

var2 變量的偏移是0109h,物理地址是 0b56:0109

這個變量是字,它占用2字節。這里假定低字節存放在低地址,

所以34h位於12h前面。
 

你可以看到,在RET指令后面還有一些指令,這樣是因為反編譯工具

無法判斷數據從什么地方開始。同樣,你可以寫出直接使用DB的程序.


#MAKE_COM#
ORG 100h

DB 0A0h
DB 08h
DB 01h

DB 8Bh
DB 1Eh
DB 09h
DB 01h

DB 0C3h

DB 7

DB 34h
DB 12h

 

將上面的代碼拷貝到emu8086原代碼編輯器,按下F5鍵編譯,並在

模擬器中運行,你可以看到同樣的反匯編結果,得到同樣的功能。

根據上面,你可以猜測,編譯器將源程序轉化為一些字節的集合,

這個集合被稱作機器代碼(machine code),處理器懂得他們,並且

執行它們。
 

ORG 100是一個編譯指令(它告訴編譯器如何處理源代碼)

當你使用變量的時侯,這條指令特別重要。它通知編譯器

可執行程序將被調入偏移量是100h(256字節)的位置,

有了它,編譯器就可以計算出所有變量的正確地址,然后

用這些地址(偏移量)來代替變量名稱。上面的這些指令

不會真正的編譯為任何機器代碼。


為何可執行程序總是被裝入偏移量100h?操作系統在CS寄存器

(代碼段)存儲着程序信息,比如命令行方式下的參數等等。

盡管上面只是一個COM文件的例子,EXE文件調入在偏移量0000

的位置,他使用特定的段保存變量。我們在下面會學習到關於

EXE文件的知識。
 



數組

數組可以看作是變量鏈。一個字符串是一個字節數組的例子,

其中每一個字符都當作一個ASCII碼的值(0....255)

下面是一些定義數組的例子

a DB 48h, 65h, 6Ch, 6Ch, 6Fh, 00h
b DB 'Hello', 0 


b是一個數組,當編譯器發現引用了字符串值后,會自動將這些

字符轉化為對應的字節。下面圖表表示的就是聲明數組后在內存

中的分布:


 
你可以使用方括號做下標直接訪問到數組中的值,例如:

MOV AL, a[3] 

同樣,你還可以使用任意一個內存索引寄存器BX, SI, DI, BP

例如:

MOV SI, 3
MOV AL, a[SI]

如果你想聲明比較復雜的數組,你可以使用DUP指令 形式如下

number DUP ( value(s) ) 
number - 重復的數量(任意常數)
value - 將要復制的表達式

例如:

c DB 5 DUP(9)

就相當於如下定義:

c DB 9, 9, 9, 9, 9 

另外一個例子:

d DB 5 DUP(1, 2)

等同於

d DB 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 
 

當然,如果需要存放超過255或者小於-128的數值,你還可以

使用DW來代替 DB。但是DW不能用於聲明字符串。
 

DUP命令展開后不能超過1020個字符(上一個例子中展開之后

是13個字符),如果需要聲明請將它們分成兩行(這樣,內存中

得到的仍然是一個大數組)。



取得變量地址 
LEA指令(Load Effective Address 讀取有效地址)或者OFFSET

指令。OFFSET 和 LEA二者都能夠獲得變量的偏移量。

LEA在使用中更有效,這是因為它能返回索引變量的地址。取得

變量地址在很多情況下是非常有用的,例如你打算向一個過程

傳遞參數。



注意:

在編譯過程中使用如下聲明數據類型
BYTE PTR - 表示字節

WORD PTR - 表示字(2個字節)

例如:

BYTE PTR [BX] ;按字節訪問
or
WORD PTR [BX] ;按字訪問

Emu8086 容許使用如下更簡潔的前綴

b. - 等價於上面的 BYTE PTR

w. - 等價於上面的 WORD PTR

有時,編譯器可以自動計算出數據類型,但是如果一個參與運算

的數是立即數,這種方法就不可靠了。





第一個例子:


ORG 100h

MOV    AL, VAR1      ; 將變量var1的數值放入al以便檢查

LEA    BX, VAR1              ; 將var1的地址存入 BX.

MOV    BYTE PTR [BX], 44h    ; 修改變量var1的內容

MOV    AL, VAR1              ; 將變量VAR1的數值放入AL以便檢查

RET

VAR1   DB  22h

END


下面是另外一個例子,用OFFSET指令代替LEA:


ORG 100h

MOV    AL, VAR1              ; 將變量VAR1的值放入AL以便檢查.

MOV    BX, OFFSET VAR1       ; 將變量VAR1的地址放入 BX.

MOV    BYTE PTR [BX], 44h    ; 修改變量VAR1內容

MOV    AL, VAR1              ;將變量VAR1的值放入 AL以便檢查.

RET

VAR1   DB  22h

END


上面例子的功能相同。

這些語句:
LEA BX, VAR1
MOV BX, OFFSET VAR1 

都將生成同樣的機器代碼: MOV BX, num
num 是16位變量偏移


請注意,只有這些寄存器可以放入方括號中(作為內存指針)

BX, SI, DI, BP(請參考本教程前述章節)
 



常量

常量同變量很相似,但是它一直存在。定義一個變量之后,它的值

不會改變。使用EQU定義常量:

name equ <任意表達式>


例如:

k EQU 5

MOV AX, k


上面的例子等同於如下代碼:

MOV AX, 5




在程序執行過程中你可以選擇模擬器"View"菜單下的"Variables"

 

你可以點一個變量然后設置Elements屬性為數組大小來查看數組。

匯編語言對於數據類型並不嚴格,這樣以來所有的變量都可以被看

作是數組。

變量可以顯示為下列進制

  • HEX - 十六進制 hexadecimal (基底 16).
  • BIN - 二進制 (基底 2).
  • OCT - 八進制 (基底 8).
  • SIGNED - 有符號十進制 (基底 10).
  • UNSIGNED - 無符號十進制 (基底 10).
  • CHAR - ASCII 碼 (一共有256個符號,其中一些符號是不可見的).

程序運行的時侯,你可以通過雙擊它來編輯變量值,或者選中

之后點Edit按鈕。

十六進制數值以"h"結尾,二進制以"b" 結尾,八進制以"o" 結尾

十進制沒有結尾。字符串用這樣的方式表示:'hello world',0

(結尾以0表示)

數組按照如下輸入:
1, 2, 3, 4, 5

(數組可以是一組字節或者字,這取決於你想以字節還是

方式編輯)

表達式會自動計算,例如,輸入如下表達式
5 + 2
會自動計算為7。等等....

 

<<< 上一部分 <<<【8086匯編基礎】02--尋址方式和MOV指令 

>>> 下一部分 >>>【8086匯編基礎】04--中斷


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM