汇编语言 过程

过程或子程序在汇编语言中非常重要,因为汇编语言程序往往很大。程序由名称标识。在此名称之后,描述了执行定义良好的作业的过程主体。返回语句表示过程结束。


语法

定义过程的语法如下:

  1. proc_name:
  2. procedure body
  3. ...
  4. ret

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

  1. CALL proc_name

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


Example

让我们编写一个名为 sum 的非常简单的过程,该过程将存储在 ECXEDX 寄存器中的变量相加,并在 EAX 寄存器中返回总和:

  1. section .text
  2. global _start ;必须声明才能使用 gcc
  3. _start: ;告诉链接器入口点
  4. mov ecx,'4'
  5. sub ecx, '0'
  6. mov edx, '5'
  7. sub edx, '0'
  8. call sum ;调用 sum 过程
  9. mov [res], eax
  10. mov ecx, msg
  11. mov edx, len
  12. mov ebx,1 ;文件描述 (stdout)
  13. mov eax,4 ;系统调用号 (sys_write)
  14. int 0x80 ;调用内核
  15. mov ecx, res
  16. mov edx, 1
  17. mov ebx, 1 ;文件描述 (stdout)
  18. mov eax, 4 ;系统调用号 (sys_write)
  19. int 0x80 ;调用内核
  20. mov eax,1 ;系统调用号 (sys_exit)
  21. int 0x80 ;调用内核
  22. sum:
  23. mov eax, ecx
  24. add eax, edx
  25. add eax, '0'
  26. ret
  27. section .data
  28. msg db "The sum is:", 0xA,0xD
  29. len equ $- msg
  30. segment .bss
  31. res resb 1

结果如下:

  1. The sum is:
  2. 9

堆栈数据结构

堆栈是内存中类似数组的数据结构,可以在其中存储数据并从称为堆栈 "顶部" 的位置删除数据。需要存储的数据被 "推" 到堆栈中,要检索的数据被从堆栈中 "弹出" 出来。堆栈是后进先出的数据结构,即先存储的数据最后检索。

汇编语言为堆栈操作提供了两条指令:PUSHPOP。这些指令的语法如下:

  1. PUSH operand
  2. POP address/register

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

堆栈实现具有以下特征:

  • 只能将字或双字保存到堆栈中,而不是字节。
  • 堆栈朝反方向增长,即朝着较低的存储器地址增长
  • 堆栈的顶部指向插入堆栈中的最后一个项目。它指向插入的最后一个字的低字节。

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

  1. ; AX BX 寄存器内容保存在堆栈中
  2. PUSH AX
  3. PUSH BX
  4. ;将寄存器用着其他用途
  5. MOV AX, VALUE1
  6. MOV BX, VALUE2
  7. ...
  8. MOV VALUE1, AX
  9. MOV VALUE2, BX
  10. ;使用完之后恢复寄存器原始值
  11. POP BX
  12. POP AX
实例

以下程序显示整个 ASCII 字符集。主程序调用一个名为 display 的过程,该过程显示 ASCII 字符集:

  1. section .text
  2. global _start ;必须声明才能使用 gcc
  3. _start: ;告诉链接器入口点
  4. call display
  5. mov eax,1 ;系统调用号 (sys_exit)
  6. int 0x80 ;调用内核
  7. display:
  8. mov ecx, 256
  9. next:
  10. push ecx
  11. mov eax, 4
  12. mov ebx, 1
  13. mov ecx, achar
  14. mov edx, 1
  15. int 80h
  16. pop ecx
  17. mov dx, [achar]
  18. cmp byte [achar], 0dh
  19. inc byte [achar]
  20. loop next
  21. ret
  22. section .data
  23. achar db '0'

结果如下:

  1. 0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}
  2. ...
  3. ...