彙編語言基礎-1 基本語言元素

1   基本語言元素:

  本次彙編語言學習,採取的是Microsoft MASA的彙編器語法規則。

1.1 第一個彙編程式

 

1 main PROC      
2     mov eax,5  ;把數字5送入暫存器eax
3     add  eax,6  ;eax暫存器加6
4     
5     INVOKE ExitProcess,0 ;程式結束
6 main ENDP  ;結束標記

  這個程式實現的是將暫存器eax賦值為5並自加6然後退出。

  採用一行一行結束這個程式碼:第一行的main PROC 是程式的入口,相當於一個C語言的main函數

  第二行是mov eax,5把數字5送入暫存器

  第三行把6加到暫存器eax上。

  第五行 調用windows服務(函數)ExitProcess停止服務。

  第六行 作為主程式結束的標誌。

 

1.2 程式分段

  為了使程式更加一目了然,架構清楚,需要添加一些標記或聲明來標識程式的程式碼和數據區分區。

  程式有程式碼段,數據段,堆棧段等等。

 1 .data     ;定義為數據區    
 2 sum DWORD 0 ;申明變數sum類型為DWORD,初值為0
 3 
 4 .code     ;定義為程式碼區
 5 main PROC
 6     mov eax,5
 7     add  eax,6
 8     mov sum,eax  ;將eax暫存器的值賦值給sum變數
 9     
10     INVOKE ExitProcess,0    ;程式結束
11 main ENDP

1.3 整數變數

格式:

[{+ | -}] digits [radix]

首先符號表示,如果為正可以省略,中間是數值,radix是基數也就是進位,如果為十進位可以省略

進位需要用縮寫來表示

二進位 八進位 十進位 和十六進位的縮寫分別是 B Q D H來表示

例子:

26    ;十進位
26D    ;十進位
11b    ;二進位
1Ah    ;十六進位
42q    ;八進位

需要注意的是如果十六進位是用字母開頭的需要在前面添加一個0防止彙編器把該數作為標識符

1.4 整形常量表達式

也就是比平時的加減乘除多了一個取模運算

運算優先順序

運算符 名稱 優先順序
()     括弧 1
*  / 乘除 2
MOD 取模 3
+ - 加減 4

1.5 實數常量

實數常量又叫浮點數常量,用來表示十進位的實數和編碼(十六進位)實數。十進位數包含一個可選符號,然後整數,然後小數點和一個可選小數部分整數和一個可選指數

【sign】integer.[integer][exponent]

sign 取值{+,-}

exponent 取值 E[{+,-}]integer

例子:

 2.

 +3.0

 -44.2E+05

 26.E5

 

1.6 字元常量

  字元常量是指用單引號或者雙引號包含的一個字元,彙編器在記憶體中保存的是字元的ASCII碼的數值

例如 'A' 就是保存的對應的ASCII碼數值保存為數字65或41h

1.7 字元串常量

  字元串常量(string literal)是用單引號或雙引號好漢的一個字元序列(包括了空格符等等),嵌套引號使用也是被允許的。

和字元常量保存一樣,字元串常量只是一個一個拆分成字元常量保存在記憶體中。

  例如:"ABCD"就包含四個位元組41h,42h,43h,44h。

 

1.8保留字

  也就是C語言的關鍵字的意思,這些保留字都是在彙編語言中有特殊含義的,不能隨便用。保留字沒有大小寫的區分,比如MOV和Mov是一樣的。

分類:

指令助記符:

  如 MOV,ADD和MUL

暫存器名稱:

  如:eax

偽指令:

  也就是告訴彙編器怎麼編程式,比如分段.data,.code這種

屬性:

  變數的屬性,比如BYTE和WORD

運算符

預定義符號

  在之前就定義了的,比如@data在彙編時返回常量的整數值

 

1.9 標識符(identity)

  由程式設計師自己選定的名稱,用來標識變數,常數,函數,子程式程式碼等等。

  標識符的規則:

    1.包含所有字元

    2.不區分大小寫

    3.第一個字元必須以字母,下劃線,@ ?或%來處理

    4.標識符不能和保留字衝突

    5.通常避免用@和下劃線作為第一個字元

 

1.10 偽指令

  偽指令(directive)是嵌入源程式碼中的命令,由彙編器識別和執行。彙編器不允許的時候執行偽指令,但是偽指令可以定義變數,宏,和子程式。給記憶體段分配名稱。默認情況下,偽指令不區分大小寫。

  由下面例子區分指令和偽指令:

  

test DWORD 26
mov    eax,test

  DWORD偽指令告訴編譯器在程式中保留一個雙字空間。mov指令在運行時,將test內容複製到eax暫存器中。

  需要注意的是Intel處理器的所有彙編器使用相同指令集,但是有著不同的偽指令。

  偽指令的功能:定義段

    彙編器偽指令的一個重要功能就是定義程式區段,也叫段(segment),程式中的段有不同作用,

      .

.data    ;數據段在這裡申明變數

.code    ; .code偽指令標識的程式區段包含了可執行的指令

.stack 100h    ;.stack偽指令的程式區段定義了運行時的堆棧大小

 

1.11 指令

  指令是一種語句,在程式彙編編譯時變得可執行,彙編器將指令翻譯為機器語言位元組,並且運行時由CPU載入執行。

  一條指令由四個部分組成:

    1.標號(可選)

    2.指令助記符(必需)

    3.操作數(一般是必需)

    4.注釋(可選)

;一般格式
[label:] mnemonic [oprands] [;comment] 

  1.11.1 標號

    標號也就是一種標識符,是指令和數據的位置標記。標號位於指令前端,表示指令的地址,同時也可以位於變數的前端,表示變數的地址。標號有兩種類型:數據標號和程式碼標號。

    數據標號標識變數的位置,提供了一種方便的手段在程式碼中引用該變數。例如:

 

count DWORD 100

      彙編器為每一個標號分配一個數學位置。可以在一個標號後面定義多個數據項。

例子:
    array DWORD 1024,2048
             DWORD   4096,8192        

    程式碼標號:

         程式碼標號用作跳轉和循環指令的目標。

         程式碼標號必須用冒號 : 來結束

;例子,下面的JMP指令創建一個循環,將程式控制傳遞給標號target表示的位置
target:
  mov  ax,bx
  ...
  jmp  target

         程式碼標號可以與指令在同一行,也可以自己獨立一行

  1.11.2 指令助記符

    指令助記符(instruction mnemonic)是標記一條指令的短單詞。

    例子:

    

助記符 說明
MOV 傳送(分配)數值
ADD 兩個數值相加
SUB 從一個數值減去另一個數值
MUL 兩個數值相乘
JMP 跳轉到一個新位置
CALL 調用一個子程式

  1.11.3 操作數

    操作數也就是指令輸入輸出的數值,彙編語言的操作個數是0-3個。可以是暫存器,記憶體操作數,整數表達式和輸出輸入埠。

    例子:

    

示例 操作數類型
96 整數常量
2+4 證書表達式
eax  暫存器
count 記憶體

    操作數個數示例:

    

stc    ;進位標誌位置,沒有操作數

;一個操作數
inc    eax    ;eax加一

;兩個操作數
mov eax,5     ;把5賦值給暫存器eax

;三個操作數

imul    eax,ebx,5    ;ebx和5相乘的結果賦值給eax

 

  1.11.4 注釋

    單行注釋 採用分號(;)

    多行注釋,用COMMENT偽指令和一個自定義符號開始。

COMMENT    I
    THIS is a comment
    this is also a comment
I

  

 

  1.11.5 NOP(空操作)指令

    nop指令,在程式中不做任何作用,但是佔有一個位元組,常用來將程式碼對其,把單位元組變成偶數位元組