2013-08-02 90 views
0

最近我开始编程c++,同时还汇编语言。我想澄清几件事情。 从我读的内容来看,指令指针从retn指令中获取应该执行的地址。不会像做jmp一样,因为jmp也设置指令指针。程序集retn,jmp,进程寄存器

如果我是对的,retnjmp有什么区别?如果我错了,有人可以用c伪代码解释吗?

什么是无限循环等同的程序集?

我看到EAX,EBX,ECX,EDX是可以互换的,但它们有什么区别吗?如果是这样,我应该在哪种情况下专门使用EAX/EBX/ECX/EDX

感谢

回答

3

你似乎在谈论子程序调用,所以这里对内幕。

当你电话一个子程序,它看起来像这样(的地址将是不同的,但我不想与可变长度指令混淆你):

1234 call 8888 
1235 <next instruction> 

什么情况是, call首先将下一个指令指针1235放到堆栈(后进先出数据结构)上,然后将指令指针设置为你正在调用的任何东西,在这种情况下为8888

后来,一回是在8889完成:

8888 mov eax, 0 
8889 ret 

什么回报也仅仅是弹出的第一个值从堆栈(即1235,这是由呼叫推),并将其装入指令指针。因此,返回告诉你要去哪里,这是通过调用推送到堆栈的信息。

如果你有你的子程序的末尾jmp指令,它会只能够恢复到一个点代码(扣除所有美好的东西,你可以与其他寻址模式现在做的):

8889 jmp 1235 

通过使用return,无论您身在何处,您都可以返回到任何地方。

loopy: 
    jmp loopy 

至于寄存器,eaxebxecxedx被认为是通用寄存器:


作为无限循环汇编器可以很简单。这将它们与诸如堆栈指针,基址指针,源指针和目标索引等更特殊用途的寄存器区分开来,这些寄存器根据其用途具有专门的指令。

ax在x86架构的非常早期的迭代中可能有一些额外的权力,但我不确定情况如何。如果你正在编写你自己的东西,你应该能够主要使用它们互换。如果您正在关注API或ABI,那么您需要遵循它强加的规则(如Linux系统调用接口,其中eax包含系统调用号)。

+0

感谢您的及时回复,我现在明白了。 – Imaginarys

0

eaxedx是除法和int乘法的宽结果版本中的隐式操作数。还有一些特殊的符号扩展指令仅对rax(操作码98)或将eax改为edx:eax(操作码99)的部分操作。小数运算指令在eax的所有部分都有效。

ecx(以及cl真的,但足够接近),是,你可以Haswell的(它引入sarxshlxshrx所有这些都可以通过任何GPR转移)之前通过移动唯一的寄存器。 ecx也被用作rep-prefixes的计数器。 pcmp*stri的长度为ecx

许多特殊用途的指令没有明确的操作数,而是赋予特殊意义的某些GPR的,例如cpuidrdpmcrdtscwrmsrxgetbvxsave。通常edx:eax,往往ecx以及很少ebx。你可能不需要处理这些。

1

retjmp在C方面的差异/ C++函数与此类似:

int foo() 
{ 
    int x = 3+4; 

    if(x < 10) 
     goto Quit; <- similar to jmp 

    x += 10; 

Quit: 
    return x;  <- similar to ret 

}

当你用C做return它更复杂一些真正发生的事情上因为通常会执行额外的代码,例如将返回值放在eax并清除堆栈。在C++中,本地对象也会被取消,但函数的最后一个将是ret指令。

什么是等效于无限循环的程序集?

while(1); 

就像

000000 jmp 000000 

或更先进的

00000 inc ecx 
00001 jmp 00000 

通用寄存器。在某些情况下,您可以混合寄存器并根据需要使用它们。对于某些说明,他们希望使用特定的寄存器。您必须查阅说明手册以查看情况。

一个例子是movsw,它需要你使用(E)SI(E)DI,所以在这种情况下你不能自由选择。如果使用rep movsw,则还使用其他(E)CX。 通常,汇编程序知道哪些寄存器对inxtruction有效,并会给出错误消息,但是当然,您应该查看手册以确保它正确,因为如果汇编程序不能抛出错误,您可能会收到意想不到的结果。

相关问题