組合語言學習07 之資料型別(結合例項分析)

2021-10-01 22:10:04 字數 3567 閱讀 8391

本文參考主要參考這個**的內容

彙編器識別一組基本的內部資料型別(intrinsic data type),按照資料大小(位元組、字、雙字等等)、是否有符號、是整數還是實數來描述其型別。

下表給出了全部內部資料型別的列表

資料定義語句(data definition statement)在記憶體中為變數留岀儲存空間,並賦予乙個可選的名字。資料定義語句根據內部資料型別(上表)定義變數。

[name] directive initializer [,initializer]

...

下面是資料定義語句的乙個例子:

count dword 2400
其中:

名字:分配給變數的可選名字必須遵守識別符號規範。

偽指令:資料定義語句中的偽指令可以是 byte、word、dword、sbtye、sword 或其他在上表中列出的型別。此外,它還可以是傳統資料定義偽指令,如下表所示

資料定義中至少要有乙個初始值,即使該值為 0。其他初始值,如果有的話,用逗號分隔。對整數資料型別而言,初始值(initializer)是整數常量或是與變數型別,如 byte 或 word 相匹配的整數表示式。

如果程式設計師希望不對變數進行初始化(隨機分配數值),可以用符號 ?作為初始值。所有初始值,不論其格式,都由彙編器轉換為二進位制資料。 初始值 0011 0010b、32h 和 50d 都具有相同的二進位制數值。

下面給出具體例子instance.asm:

;instance.asm

.386

.model flat,stdcall

.stack 4096

exitprocess proto, dwexitcode:dword

.data

sum dword 0

.code

main proc

mov eax,3

add eax,4

mov sum,eax

invoke exitprocess,0

main endp

end main

第一行在;後面表示注釋

第 2行是 .386 偽指令,它表示這是乙個 32 位程式,能訪問 32 位暫存器和位址。

第 3 行選擇了程式的記憶體模式(flat),並確定了子程式的呼叫規範(稱為 stdcall)。其原因是 32 位 windows 服務要求使用 stdcall 規範。

第 4行為執行時堆疊保留了 4096 位元組的儲存空間,每個程式都必須有。

第 5 行宣告了 exitprocess 函式的原型,它是乙個標準的 windows 服務。原型包含了函式名、proto 關鍵字、乙個逗號,以及乙個輸入引數列表。exitprocess 的輸入引數名稱為 dwexitcode。

可以將其看作為給 windows 作業系統的返回值,**返回值為零,則表示程式執行成功;**而任何其他的整數值都表示了乙個錯誤**。因此,程式設計師可以將自己的匯程式設計序看作是被作業系統呼叫的子程式或過程。當程式準備結束時,它就呼叫 exitprocess,並向作業系統返回乙個整數以表示該程式執行良好。

第6行表示資料區

第7行表示資料變數sum,並初始化為0

第8行.code 偽指令標記乙個程式**區的起點,**區包含了可執行指令。通常,.code 的下一行宣告程式的入口,按照慣例,一般會是乙個名為 main 的過程。程式的入口是指程式要執行的第一條指令的位置。

後面則是主程式的運算。

byte(定義位元組)和 sbyte(定義有符號位元組)為乙個或多個無符號或有符號數值分配儲存空間。每個初始值在儲存時,都必須是 8 位的。

問號(?)初始值使得變數未初始化,這意味著在執行時分配數值到該變數:

val byte ?    ;表示定義了val,但是沒有初始化值
如果同乙個資料定義中使用了多個初始值,那麼它的標號只指出第乙個初始值的偏移量。在下面的例子中,假設 list 的偏移量為 0000。那麼,數值 1 的偏移量就為 0000, 2 的偏移量為 0001,3 的偏移量為 0002,4 的偏移量為 0003:

list byte 1,2,3,4
並不是所有的資料定義都要用標號。比如,在 list 後面繼續新增位元組陣列,可以按照如下定義:

list byte 1,2,3,4

byte 5,6,7,8

定義乙個字串,要用單引號或雙引號將其括起來。最常見的字串型別是用乙個空位元組(值為0)作為結束標記,稱為以空位元組結束的字串。如下例子:

string1 byte "hello",0

string2 byte 'world',0

乙個字串可以分為多行,如下所示:

string1   byte "welcome to the new world of asm "

byte "it sucks",0dh, 0ah

byte "but you will love it",0dh,0ah,0

十六進製制** 0dh 和 0ah 也被稱為 cr/lf (回車換行符)或行結束字元。

word(定義字)和 sword(定義有符號字)偽指令為乙個或多個 16 位整數分配儲存空間:

world1 word 65535    ;最大無符號數

world2 sword -32768 ;最小有符號數

word word ? ;未初始化,無符號

16 位字陣列通過列舉元素或使用 dup 操作符來建立字陣列。下面的陣列包含了一組數值:

mylist word 10,20,30,40,50
假設 mylist 起始位置偏移量為0000。由於每個數值佔兩個位元組,因此其位址遞增量為 2。

real4 定義 4 位元組單精度浮點變數。real8 定義 8 位元組雙精度數值,real10 定義 10 位元組擴充套件精度數值。每個偽指令都需要乙個或多個實常數初始值:

rval1 real4 -1.2

rval2 real8 3.2e-260

rval3 real10 4.6e+4096

shortarray real4 20 dup(0.0)

x86 處理器在記憶體中按小端(little-endian)順序(低到高)存放和檢索資料。最低有效位元組存放在分配給該資料的第乙個記憶體位址中,剩餘位元組存放在隨後的連續記憶體位置中。考慮乙個雙字 12345678h。如果將其存放在偏移量為 0000 的位置,則 78h 存放在第乙個位元組,56h 存放在第二個位元組,餘下的位元組存放位址偏移量為 0002 和 0003。如下圖所示:

組合語言學習

參考書籍 組合語言 王爽 著 清華大學出版社 選單導航 一 彙編基礎知識 二 暫存器和常見彙編指令演示 一 基礎知識 1 彙編指令是機器指令的助記符,同機器指令一一對應 2 每一種cpu都有自己的彙編指令集 3 cpu可以直接使用的資訊在儲存器中存放 4 在儲存器中指令和資料沒有任何區別,都是二進位...

組合語言學習

持續更新 彙編指令 1.mov指令 mov是乙個傳送指令,可以實現以下操作 有一點需要注意,資料不能直接傳給段暫存器,比如mov ds,100h就是錯誤的。但是可以將其他暫存器中的值賦給段暫存器。段暫存器有cs,ds,ss,es等。如果你想知道為什麼,那就可以去了解一下關於每條指令的硬體實現。後面還...

組合語言 學習資料(更新 )

學彙編不是說一定要用這玩藝做多牛鼻的事情,問題的關鍵在於,學透了彙編會使你真正理解計算機另外一方面,如上面所說,在工作中你遲早會在某個陰暗的角落遇到彙編.不管你承認不承認,現在的cpu沒有直接跑高階語言的,哪怕是虛擬機器也都是類似彙編的指令集.當遇到崩潰分析,效能優化甚至編譯器抽風等等的時候,彙編是...