汇编语言 过程

  • 过程

    过程或子例程在汇编语言中非常重要,因为汇编语言程序往往会很大。程序由名称标识。在此名称之后,将描述执行明确定义的作业的过程主体。该过程的结束由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)将偏移量设置为堆栈段。
    堆栈实现具有以下特征-
    • 只能将字或双字保存到堆栈中,而不是字节。
    • 堆栈朝反方向增长,即朝着较低的存储器地址增长
    • 堆栈的顶部指向插入堆栈中的最后一个项目。它指向插入的最后一个字的低字节。
    正如我们所讨论的,在将寄存器的值用于某些用途之前将其存储在堆栈中;它可以通过以下方式完成-
    
    ; 将AX和BX寄存器内容保存在堆栈中
    PUSH    AX
    PUSH    BX
    
    ;将寄存器用着其他用途
    MOV     AX, VALUE1
    MOV     BX, VALUE2
    ...
    MOV     VALUE1, AX
    MOV     VALUE2, BX
    
    ;使用完之后恢复寄存器原始值
    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{|}
    ...
    ...