• 汇编语言基础之三 变量的访问和流程控制指令


    访问变量

    与其他等级的编程语言一样,汇编语言能够用许多方式来访问变量。变量有三种基本的存储方式。

    1. 全局变量/静态变量- 在程序数据区(program data section)分配

    2. 局部变量/参数- 在栈上分配

    3. 堆变量- 在堆上分配

    全局,静态变量

    全局变量存储在一个固定的地址上(至少对于程序来说,他们是固定的)。访问这些变量的最通常的方式是在指令中明确指出那个固定的地址。

    MOV    EAX,[1234134H]        ; loads EAX with value stored at location 12341234H

    INC      DWORD PTR TEST2!_nCount ; increments DWORD variable nCount

    注意,在symbolic信息可用的时候,debugger会去使用它。

    局部变量,参数

    局部变量和参数存在于栈上,并且是通过EBP(有时候是ESP)来访问的。优化过的代码通常会清除掉对栈基指针(frame pointer)的依赖,在这样的情况下ESP寄存器被用来访问局部变量,而EBP可以被用来做一个额外的通用寄存器来使用。当你使用一个标准栈基指针的时候,指令看起来应该是这样的。

    MOV   EAX,[EBP+8]   ; load EAX with argument

    MOV   EAX,[EBP-4]    ; load EAX with local variable

    有一个记忆的小窍门,当EBP没有作为通用寄存器使用的时候,也就是绝大多数时候,当位移是正的时候,访问的是参数。当位移是负的时候,访问的是局部变量。

    注意,典型的第一个传递给函数的参数是EBP+8

    堆变量

    堆变量存在于堆上,他们是通过指针来访问的。典型情况下需要不只一条指令来访问堆变量。

    MOV   ESI, TEST2!_m_pFileList     ; load the pointer

    MOV   EAX, [Esi+4]                         ; read second DWORD (pszName) in heap

    另一个需要注意的是,大多数编译器会将经常访问的变量放到寄存器中,以便于提高访问速度。尤其是精简指令计算机。

    执行流控制

    控制流命令要不就是有条件的(条件满足的时候),要不就是无条件的。这些语句支持函数调用,if-then-else,switch case等高级的语言成分。

    无条件跳转指令

    1. JMP命令

        这个命令简单的设置EIP寄存器为下一条指令的地址。没有任何数据会被存储到栈上,并且不会设置任何标志位。JMP被用在固定的指令分支上。大多数的if-then-else语句族至少需要一条JMP指令。

    2. CALL命令

        这条指令先存储EIP的值到栈上,然后设置EIP为下一条指令的地址。将EIP压栈允许程序在结束了函数调用之后,回来继续执行CALL语句后面的语句。

    对于JMP和CALL指令来说,操作数可以是固定的地址,寄存器的值,或者一个指向分支地址的指针。

    3. RET命令

        RET指令将当前栈上的值赋给EIP寄存器。该命令用来为传递给栈的参数修复栈指针。

    4. INT命令

        当INT命令的操作数是一个中断号的时候,该指令会引发一个软件中断。这个与CALL指令差不多,不同之处是EFLAGS寄存器被压入栈中。还有,如果是在user mode中被调用,在切换到kernel mode时也会发生将EFLAG寄存器压栈的操作。中断函数结束的时候,随着RETI指令的执行,EFLAGS寄存器和EIP都会从栈中恢复。

    条件跳转指令

    1, LOOP Adress

        LOOP指令被用来实现高级语言中的循环。直到ECX(计数器)的值为0的时候,它才会走向分支地址。如果ECX不是0,那么ECX会被减一,然后继续循环操作。

    XOR     EAX,EAX    ; clear EAX register

    MOV    ECX, 5        ; load loop count

    START:

    ADD     EAX,1         ; add one to eax

    LOOP  START

    2. JNX,JE等等

        根据条件来跳转的指令会去判断所指定的条件是否为真,若果是就执行跳转。比如,JNZ(jump not zero),操作数中指定的地址直到ZERO标志位被设置为1的时候才会被转过去。这些指令主要被用在if语句块中。

    XOR    EAX,EAX   ; clear eax

    MOV    ECX,5

    START:

    ADD    EAX,1       ; add one to EAX

    DEC    ECX          ; decrement loop counter

    JNZ     START

  • 相关阅读:
    Lyft Level 5 Challenge 2018
    Codeforces Round #514 (Div. 2)题解
    Bubble Cup 11
    不如来搞一下CDQ分治吧!
    Codeforces Round #331 (Div. 2)
    写一下中国剩余定理的证明
    codeforces Round#332Div2 题解
    GCPC2017 题解
    2017 USP Try-outs 题解
    CodeForce 387D. George and Interesting Graph
  • 原文地址:https://www.cnblogs.com/awpatp/p/1593459.html
Copyright © 2020-2023  润新知