彙編 - 過程
過程或子程式在組合語言中非常重要,因為組合語言程式往往規模很大。過程由名稱標識。在該名稱之後,描述了執行明確定義工作的過程主體。過程的結束由 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{|}
...
...
廣告