汇编语言 过程
过程或子程序在汇编语言中非常重要,因为汇编语言程序往往很大。程序由名称标识。在此名称之后,描述了执行定义良好的作业的过程主体。返回语句表示过程结束。
语法
定义过程的语法如下:
proc_name:procedure body...ret
通过使用 CALL 指令从另一个函数调用该过程。CALL 指令应将被调用过程的名称作为参数,如下所示:
CALL proc_name
被调用的过程使用 RET 指令将控件返回给调用过程。
Example
让我们编写一个名为 sum 的非常简单的过程,该过程将存储在 ECX 和 EDX 寄存器中的变量相加,并在 EAX 寄存器中返回总和:
section .textglobal _start ;必须声明才能使用 gcc_start: ;告诉链接器入口点mov ecx,'4'sub ecx, '0'mov edx, '5'sub edx, '0'call sum ;调用 sum 过程mov [res], eaxmov ecx, msgmov edx, lenmov ebx,1 ;文件描述 (stdout)mov eax,4 ;系统调用号 (sys_write)int 0x80 ;调用内核mov ecx, resmov edx, 1mov ebx, 1 ;文件描述 (stdout)mov eax, 4 ;系统调用号 (sys_write)int 0x80 ;调用内核mov eax,1 ;系统调用号 (sys_exit)int 0x80 ;调用内核sum:mov eax, ecxadd eax, edxadd eax, '0'retsection .datamsg db "The sum is:", 0xA,0xDlen equ $- msgsegment .bssres resb 1
结果如下:
The sum is:9
堆栈数据结构
堆栈是内存中类似数组的数据结构,可以在其中存储数据并从称为堆栈 "顶部" 的位置删除数据。需要存储的数据被 "推" 到堆栈中,要检索的数据被从堆栈中 "弹出" 出来。堆栈是后进先出的数据结构,即先存储的数据最后检索。
汇编语言为堆栈操作提供了两条指令:PUSH 和 POP。这些指令的语法如下:
PUSH operandPOP address/register
堆栈段中保留的内存空间用于实现堆栈。寄存器 SS 和 ESP(或 SP)用于实现堆栈。SS:ESP 寄存器指向堆栈的顶部,该顶部指向插入到堆栈中的最后一个数据项,其中 SS 寄存器指向堆栈段的开头,而 SP(或 ESP)将偏移量设置为堆栈段。
堆栈实现具有以下特征:
- 只能将字或双字保存到堆栈中,而不是字节。
- 堆栈朝反方向增长,即朝着较低的存储器地址增长
- 堆栈的顶部指向插入堆栈中的最后一个项目。它指向插入的最后一个字的低字节。
正如我们所讨论的,在将寄存器的值用于某些用途之前将其存储在堆栈中。它可以通过以下方式完成:
; 将 AX 和 BX 寄存器内容保存在堆栈中PUSH AXPUSH BX;将寄存器用着其他用途MOV AX, VALUE1MOV BX, VALUE2...MOV VALUE1, AXMOV VALUE2, BX;使用完之后恢复寄存器原始值POP BXPOP AX
实例
以下程序显示整个 ASCII 字符集。主程序调用一个名为 display 的过程,该过程显示 ASCII 字符集:
section .textglobal _start ;必须声明才能使用 gcc_start: ;告诉链接器入口点call displaymov eax,1 ;系统调用号 (sys_exit)int 0x80 ;调用内核display:mov ecx, 256next:push ecxmov eax, 4mov ebx, 1mov ecx, acharmov edx, 1int 80hpop ecxmov dx, [achar]cmp byte [achar], 0dhinc byte [achar]loop nextretsection .dataachar db '0'
结果如下:
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}......