彙編 - 過程



過程或子程式在組合語言中非常重要,因為組合語言程式往往規模很大。過程由名稱標識。在該名稱之後,描述了執行明確定義工作的過程主體。過程的結束由 return 語句指示。

語法

以下是定義過程的語法:

proc_name:
   procedure body
   ...
   ret

透過使用 CALL 指令從另一個函式呼叫過程。CALL 指令應以被呼叫過程的名稱作為引數,如下所示:

CALL proc_name

被呼叫過程透過使用 RET 指令將控制權返回給呼叫過程。

示例

讓我們編寫一個名為 sum 的非常簡單的過程,它將儲存在 ECX 和 EDX 暫存器中的變數相加,並將總和返回到 EAX 暫存器:

section	.text
   global _start        ;must be declared for using gcc
	
_start:	                ;tell linker entry point
   mov	ecx,'4'
   sub     ecx, '0'
	
   mov 	edx, '5'
   sub     edx, '0'
	
   call    sum          ;call sum procedure
   mov 	[res], eax
   mov	ecx, msg	
   mov	edx, len
   mov	ebx,1	        ;file descriptor (stdout)
   mov	eax,4	        ;system call number (sys_write)
   int	0x80	        ;call kernel
	
   mov	ecx, res
   mov	edx, 1
   mov	ebx, 1	        ;file descriptor (stdout)
   mov	eax, 4	        ;system call number (sys_write)
   int	0x80	        ;call kernel
	
   mov	eax,1	        ;system call number (sys_exit)
   int	0x80	        ;call kernel
sum:
   mov     eax, ecx
   add     eax, edx
   add     eax, '0'
   ret
	
section .data
msg db "The sum is:", 0xA,0xD 
len equ $- msg   

segment .bss
res resb 1

編譯並執行上述程式碼後,將產生以下結果:

The sum is:
9

棧資料結構

棧是記憶體中類似陣列的資料結構,可以在其中儲存資料並從稱為棧“頂部”的位置移除資料。需要儲存的資料被“壓入”棧中,需要檢索的資料被“彈出”棧中。棧是一種 LIFO 資料結構,即先儲存的資料最後檢索。

組合語言提供了兩個用於棧操作的指令:PUSH 和 POP。這些指令的語法如下:

PUSH    operand
POP     address/register

棧段中預留的記憶體空間用於實現棧。暫存器 SS 和 ESP(或 SP)用於實現棧。棧的頂部指向插入到棧中的最後一個數據項,由 SS:ESP 暫存器指向,其中 SS 暫存器指向棧段的開頭,SP(或 ESP)給出棧段中的偏移量。

棧的實現具有以下特徵:

  • 只能將雙字儲存到棧中,不能儲存位元組。

  • 棧向相反方向增長,即向較低的記憶體地址增長。

  • 棧的頂部指向插入到棧中的最後一個專案;它指向插入的最後一個字的低位元組。

正如我們討論過在使用暫存器值之前將其儲存在棧中的方法;可以透過以下方式完成:

; Save the AX and BX registers in the stack
PUSH    AX
PUSH    BX

; Use the registers for other purpose
MOV	AX, VALUE1
MOV 	BX, VALUE2
...
MOV 	VALUE1, AX
MOV	VALUE2, BX

; Restore the original values
POP	BX
POP	AX

示例

以下程式顯示整個 ASCII 字元集。主程式呼叫一個名為 display 的過程,該過程顯示 ASCII 字元集。

section	.text
   global _start        ;must be declared for using gcc
	
_start:	                ;tell linker entry point
   call    display
   mov	eax,1	        ;system call number (sys_exit)
   int	0x80	        ;call kernel
	
display:
   mov    ecx, 256
	
next:
   push    ecx
   mov     eax, 4
   mov     ebx, 1
   mov     ecx, achar
   mov     edx, 1
   int     80h
	
   pop     ecx	
   mov	dx, [achar]
   cmp	byte [achar], 0dh
   inc	byte [achar]
   loop    next
   ret
	
section .data
achar db '0'  

編譯並執行上述程式碼後,將產生以下結果:

0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}
...
...
廣告

© . All rights reserved.