Assembly彙編 過程

過程或子程序在彙編語言是很重要的,彙編語言程序往往是規模大。過程是由一個名稱標識。按照這一名稱,在過程體(body)中進行了描述,其中執行一個明確定義的工作。一個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 yiibai
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

堆棧的數據結構:

堆棧是一個類似數組的數據結構在存儲器中的數據可以被存儲和刪除的位置被稱爲「頂層」堆棧。是'推'入堆棧,要檢索的數據是'彈出'從堆棧中的數據需要存儲。堆棧是一個後進先出的數據結構,即先存儲,數據檢索。

彙編語言提供了兩種的堆棧操作說明: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 AX
POP BX

例子:

下面的程序顯示了整個ASCII字符集。主程序調用一個程序命名爲display,顯示的ASCII字符集。 

section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry yiibai
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{|}
...
...