汇编 - 过程



过程或子程序在汇编语言中非常重要,因为汇编语言程序往往规模很大。过程由名称标识。在该名称之后,描述了执行明确定义工作的过程主体。过程的结束由 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{|}
...
...
广告