当前位置: 首页 > 文档资料 > 汇编中文教程 >

程序(Procedures)

优质
小牛编辑
137浏览
2023-12-01

程序或子程序在汇编语言中非常重要,因为汇编语言程序的大小往往很大。 程序由名称标识。 遵循此名称,描述了执行明确定义的作业的过程的主体。 程序结束由return语句指示。

语法 (Syntax)

以下是定义过程的语法 -

proc_name:
   procedure body
   ...
   ret

通过使用CALL指令从另一个函数调用该过程。 CALL指令应该将被调用过程的名称作为参数,如下所示 -

CALL proc_name

被调用过程使用RET指令将控制返回给调用过程。

例子 (Example)

让我们编写一个名为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

堆栈数据结构

堆栈是存储器中类似于阵列的数据结构,其中数据可以被存储并从称为堆栈的“顶部”的位置移除。 需要存储的数据被“推送”到堆栈中,要检索的数据从堆栈中“弹出”。 Stack是LIFO数据结构,即最后检索的数据是最后检索的。

汇编语言提供了两种堆栈操作说明:PUSH和POP。 这些说明的语法如下 -

PUSH    operand
POP     address/register

堆栈段中保留的内存空间用于实现堆栈。 寄存器SS和ESP(或SP)用于实现堆栈。 堆栈的顶部指向插入堆栈的最后一个数据项,由SS:ESP寄存器指向,其中SS寄存器指向堆栈段的开头,SP(或ESP)将偏移量指向堆栈段。

堆栈实现具有以下特征 -

  • 只有wordsdoublewords可以保存到堆栈中,而不是字节。

  • 堆栈沿相反方向增长,即朝向较低的存储器地址

  • 堆栈顶部指向堆栈中插入的最后一项; 它指向插入的最后一个单词的低位字节。

正如我们讨论的那样,在将寄存器的值用于某些用途之前将其存储在堆栈中; 它可以通过以下方式完成 -

; 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

例子 (Example)

以下程序显示整个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{|}
...
...