b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

汇编esp是什么意思_汽车esp是什么意思_esp故障是什么意思(2)

电脑杂谈  发布时间:2019-09-11 09:05:02  来源:网络整理

shl <reg>,<con8>

shl <mem>,<con8>

shl <reg>,<cl>

shl <mem>,<cl>

shr <reg>,<con8>

shr <mem>,<con8>

shr <reg>,<cl>

shr <mem>,<cl>

Examples

shl eax, 1 — Multiply the value of EAXby 2 (if the most significant bit is 0),左移1位,相当于乘以2

shr ebx, cl — Store in EBX the floor of result of dividing the value of EBXby 2n where n is the value in CL.

3.3 控制转移指令

X86处理器维持着一个指示当前执行指令的指令指针(IP),当一条指令执行后,此指针自动指向下一条指令。IP寄存器不能直接操作,但是可以用控制流指令更新。

一般用标签(label)指示程序中的指令地址,在X86汇编代码中,可以在任何指令前加入标签。如:

       mov esi, [ebp+8]
begin: xor ecx, ecx
       mov eax, [esi]

如第二条指令用begin指示,这种标签的方式在某些程度上简化了汇编程序设计,控制流指令通过标签实现程序指令跳转。

jmp — Jump

控制转移到label所标示的地址,(从label中取出执行执行),如下所示:

jmp <label>

Example

jmp begin — Jump to the instructionlabeled begin.

jcondition— Conditional Jump

条件转移指令,条件转移指令依据机器状况字中的一些列条件状况转移。机器状态字中包含指示最后一个算数运算结果能否为0,运算结果能否为负数等。机器状况字准确解释请见微机原理、计算机构成等课程。语法如下所示:

je <label> (jump when equal)

jne <label> (jump when not equal)

jz <label> (jump when last result was zero)

jg <label> (jump when greater than)

jge <label> (jump when greater than or equal to)

jl <label> (jump when less than)

jle <label>(jump when less than or equal to)

Example

cmp eax, ebx

汽车esp是什么意思_esp故障是什么意思_汇编esp是什么意思

jle done , 如果eax中的值大于ebx中的值,跳转到done指示的区域执行,否则,执行下一条指令。

cmp— Compare

cmp指令比较两个操作数的值,并按照相当结果修改机器状况字中的条件码。此指令与sub指令类似,但是cmp不用将计算结果保存在操作数中。其语法如下所示:

cmp <reg>,<reg>

cmp <reg>,<mem>

cmp <mem>,<reg>

cmp <reg>,<con>

Example

cmp DWORD PTR [var], 10

jeq loop,

比较var指示的4字节内容能否为10,如果不是,则再次执行下一条指令,否则,跳转到loop指示的指令开始执行

call, ret— Subroutine call and return

这两条指令实现子程序(过程、函数等含义)的读取及返回。call指令首先将当前执行指令地址入栈,然后无条件转移到由标签指示的指令。与其他简洁的跳转指令不同,call指令保存读取之前的地址信息(当call指令结束后,返回到调用之前的地址)。

ret指令实现子程序的返回机制,ret指令弹出栈中保存的指令地址,然后无条件转移到保存的指令地址执行。

call,ret是变量调用中最关键的两条指令。具体细节见上面一部分的详解。语法为:

call <label>

4 调用规则

为了提高程序员之间的协同及简化程序研发进程,设定一个函数读取规则非常必要,函数读取规则要求数组读入及返回的规则,只要按照这样规则写的程序均可以恰当执行,从而程序员不必关心诸如参数怎么释放等难题;另一方面,在汇编语言中可以读取符合这些规则的高级语言所写的变量,从而将汇编语言程序与高级语言程序有机结合在一起。

调用规则分为两个方面,及调用者规则和被调用者规则,如一个函数A调用一个函数B,则A被称为调用者(Caller),B被称为被调用者(Callee)。

下图显示一个调用过程中的存储中的栈布局:

栈布局

在X86中,栈增长方向与存储编号增长方向相反。

调用者规则包含一系列操作,描述如下:

1)在读取子程序之前,调用者应该保存一系列被设计为调用者保存的解释器的值。调用者保存寄存器有eax,ecx,edx。由于被读取的子程序会设置很多寄存器,所以为了在读取子程序完成以后能恰当执行,调用者必须在读取子程序之前将这种寄存器的值入栈。

2)在读取子程序之前,将参数入栈。参数入栈的排序需要是从最后一个参数开始,如上图中parameter3先入栈。

3)利用call指令调用子程序。这条指令将返回地址放置在参数的里面,并开启子程序的指令执行。(子程序的执行将根据被调用者的规则执行)

当子程序返回时,调用者期望找到子程序保存在eax中的返回地址。为了恢复调用子程序执行之前的状况,调用者应该执行下面操作:

1)清除栈中的参数;

2)将栈中保存的eax值、ecx值以及edx值出栈,恢复eax、ecx、edx的值(当然,如果其他寄存器在读取之前需要储存,也应该完成类似入栈和出栈操作)

Example

如下代码展示了一个调用子程序的调用者应该执行的操作。此汇编程序读取一个具有三个参数的变量_myFunc,其中第一个参数为eax,第二个参数为系数216,第三个参数为var指示的存储中的值。

push [var] ; Push last parameter first
push 216   ; Push the second parameter
push eax   ; Push first parameter last
call _myFunc ; Call the function (assume C naming)
add esp, 12

在读取返回时,调用者必须清除栈中的相应内容,在上例中,参数占有12个字节,为了防止这种参数,只需将ESP加12即可。

_myFunc的值保存在eax中,ecx和edx中的值可能早已被颠覆,调用者还需要在读取之前保存在栈中,并在读取结束以后,出栈恢复ecx和edx的值。

被调用者应该遵守如下规则:

1)将ebp入栈,并将esp中的值拷贝到ebp中,其汇编代码如下:

    push ebp
    mov  ebp, esp

上述代码的目的是储存调用子程序之前的基址指针,基址指针用于寻找栈上的参数和局部变量。当一个子程序开始执行时,基址指针保存栈指针指示子程序的执行。为了在子程序完成以后调用者能恰当定位调用者的参数和局部变量,ebp的值应该返回。

2)在栈上为局部变量分配空间。

3)保存callee-saved寄存器的值,callee-saved寄存器包括ebx,edi和esi,将ebx,edi和esi压栈。

4)在上述三个步骤完成以后,子程序开始执行,当子程序返回时,必须完成如下工作:

4.1)将返回的执行结果保存在eax中

4.2)弹出栈中保存的callee-saved寄存器值,恢复callee-saved寄存器的值(ESI和EDI)

4.3)收回局部变量的存储空间。实际处理时,通过改变EBP的值就能:movesp,ebp。

4.4)通过弹出栈中保存的ebp值恢复调用者的基址寄存器值。

4.5)执行ret指令返回到调用者程序。

After these three actions are performed, the body of the subroutine may proceed. When the subroutine is returns, it must follow these steps:

Leave the return value in EAX.

Example

.486
.MODEL FLAT
.CODE
PUBLIC _myFunc
_myFunc PROC
  ; Subroutine Prologue
  push ebp     ; Save the old base pointer value.
  mov ebp, esp ; Set the new base pointer value.
  sub esp, 4   ; Make room for one 4-byte local variable.
  push edi     ; Save the values of registers that the function
  push esi     ; will modify. This function uses EDI and ESI.
  ; (no need to save EBX, EBP, or ESP)
  ; Subroutine Body
  mov eax, [ebp+8]   ; Move value of parameter 1 into EAX
  mov esi, [ebp+12]  ; Move value of parameter 2 into ESI
  mov edi, [ebp+16]  ; Move value of parameter 3 into EDI
  mov [ebp-4], edi   ; Move EDI into the local variable
  add [ebp-4], esi   ; Add ESI into the local variable
  add eax, [ebp-4]   ; Add the contents of the local variable
                     ; into EAX (final result)
  ; Subroutine Epilogue 
  pop esi      ; Recover register values
  pop  edi
  mov esp, ebp ; Deallocate local variables
  pop ebp ; Restore the caller's base pointer value
  ret
_myFunc ENDP
END

子程序首先借助入栈的方式储存ebp,分配局部变量,保存寄存器的值。

在子程序体中,参数和局部变量均是借助ebp进行推导。由于参数传递在子程序被读取之前,所以参数总是在ebp指示的地址的下方(在栈中),因此,上例中的第一个参数的地址是ebp+8,第二个参数的地址是ebp+12,第三个参数的地址是ebp+16;而局部变量在ebp指示的地址的上面,所有第一个局部变量的地址是ebp-4,而第二个这是ebp-8.


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-122495-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    每日福利
    热点图片
    拼命载入中...