从今天起开始学习intel汇编(三) 过程

本文深入探讨了栈的基本概念及其在计算机程序中的应用。详细介绍了32位系统的运行时栈管理,包括压栈和出栈操作,并解释了PUSH、POP等指令的功能。此外,还介绍了过程的定义与调用机制,包括CALL和RET指令的作用,以及如何通过流程图展示程序逻辑。

  一 堆栈

    栈是一种后进先出的结构, 这是因为最后压入栈的值总是最先被取出,

  1.运行时栈

    运行时栈由CPU直接管理,它使用两个寄存器, SS和ESP, 在保护模式下, SS寄存器存放的段选择子, 用户模式应对它进行修改,。ESP是指向堆栈内某 

    个特定的位置

    压栈操作

    32位的压栈操作首先将栈指针减4, 然后把值直接复制到指针所指向的位置,

    

    出栈操作

    出栈操作从堆栈顶端一走一个值并将其复制到寄存器或内存变量中,弹出值后,堆栈指针相应的增加, 

    

  2.堆栈的应用

    堆栈可以方便的作为临时区域,在寄存器使用完毕后, 可以通过堆栈恢复其原始值

    CALL指令执行时, CPU用堆栈保存当前调用过程的返回地址

    调用过程中,可以通过压栈传入参数

    过程内的局部变量在堆栈上创建, 过程结束时, 这些变量被丢弃

二 PUSH和POP指令

  1.PUSH指令

    PUSH执行压栈操作, 先将ESP的值减小, 然后把一个16位或者32位的源操作数复制到堆栈上, 对于16位操作数, ESP值将减小, 对于32位操作数, ESP将减4, 有以下3中格式

    PUSH r/m16

    PUSH r/m32

    push imm32

  2.POP指令

    先将ESP的值复制到目的操作数中, 然后增加ESP的值

    pop r/m16

    pop r/m32

  3. PUSHFD , POPFD

    PUSHFD 指令在堆栈上压入32位的EFLAGS寄存器的值,POPFD指令将堆栈顶部的值弹出送到EFLAGS寄存器中

    MOV指令不能复制标志寄存器中的值到变量或者寄存器中, 使用pushfd 和 POPFD注意要成对使用, 不要跳过POPFD

  4. PUSHAD, PUSHA, POPAD, POPA

    PUSHAD 指令在堆栈上按顺序压入32位寄存器:EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,

    POPAD以相反的顺序弹出这些通用的寄存器,PUSHA和POPA则是16位的操作

三过程的定义与使用

    1.PROC指令

    可以把过程非正式的定义为以返回语句结束的明明语句块, 过程使用PROC和ENDP伪指令来声明, 另外还可以给过程定义一个名字。

    sample PROC

    .

    .

    ret

    samp ENDP

四 CALL和RET指令

    1.CALL指令 只是处理器在新的内存地址执行指令, 以实现对过程的调用, 过程使用RET指令使处理器返回到被调用的地方继续执行, 从底层细节来讲,

    call指令把返回地址压入堆栈并把新地址复制到指令寄存器EIP中。RET指令弹出返回地址EIP

    2.向过程传递寄存器参数

五. 流程图

    流程图以图形化的方式描述程序逻辑。流程图每个图形都代表了一个逻辑步骤, 用带箭头的线将图形连接起来表示了逻辑步骤:

    

     我们为数组求和画一个流程图:

    

六 保存和恢复寄存器

    1.USES 操作符

    与PROC伪指令配套使用的USES操作符允许列出被过程修改的所有寄存器, 它指示编译器做两件事, 首先, 在过程开始处PUSH列出的寄存器, 其次在过程结束处POP列出的寄存器。

    ArraySum PROC USES esi, ecx

        mov eax, 0

    L1:

        add eax, [esi]

        inc esi

        loop L1

         ret

    ArraySum ENDP

    但是如果过程将某些寄存器作为返回值是不要使用USES列出该寄存器

    一个数组求和的例子

    INCLUDE Irvine32.inc
    INTEGER_COUNT = 3
   .data
    str1 BYTE "Enter a signed integer:", 0
    str2 BYTE "the sum integer is:", 0
    array DWORD INTEGER_COUNT DUP(?)
    .code
    main PROC
call Clrscr
mov esi, OFFSET array
mov ecx, INTEGER_COUNT
call PromptForIntegers
call ArraySum
call DisplaySum
exit
    main ENDP


    PromptForIntegers PROC uses ecx edx esi
mov edx, OFFSET str1
    L1: call WriteString
call ReadInt
call Crlf
mov [esi], eax
add esi, TYPE DWORD
loop L1
ret
   PromptForIntegers ENDP
   ArraySum PROC USES esi ecx
  mov eax, 0
    L1: add eax, [esi]
add esi, TYPE DWORD
loop L1
ret
    ArraySum ENDP
    DisplaySum PROC USES edx
mov edx, OFFSET str2
call WriteString
call WriteInt
call Crlf
ret
    DisplaySum ENDP
    END main 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值