寄存器和堆栈的大小在汇编x86中的意义是什么

时间:2016-08-20 15:39:44

标签: assembly x86

我刚刚参加集会,我真的很困惑,我读过几篇文章和书籍,但我无法理解这是什么意思

在汇编x86中,我们有不同的寄存器,每个寄存器都有特定的大小,例如

EAX:32位

Q1-真正意味着32位是什么意思?这是否意味着,我只能存储32位大小的值?

如果是

Q2 - 如果我有很长的字符串我怎么能把这个字符串移动到我的寄存器?

问题3 - 我想确切知道何时应该从堆栈推送和弹出?

Q4我可以将我的值存储在没有堆栈的寄存器中,为什么我们有堆栈?解决哪个问题?

如果我们在这里举例,那就是我的C代码:

#include<stdio.h>

main() 
{
    printf("Hello World");

}

这里我们将Hello world传递给printf函数,我可以传递任何大小不管,如果我把这个代码翻译成汇编,首先我必须将系统调用args到寄存器然后调用系统调用然后是int 0x80。如果你好世界的我有一个段落怎么样?

Q5 - 当我将任何数据移动到寄存器时,我如何选择应该移动数据的寄存器?

谢谢。

1 个答案:

答案 0 :(得分:3)

注册商店编号。就是这样。这就是他们所做的一切。这就是程序员使用解释那些让程序运作的数字的方式。

  • 每个寄存器的大小为8,16,32或64位。它们可以存储签名无符号数字 - 也就是说,它们的顶部位是被解释为符号位还是仅作为数字的一部分。请注意,这些数字可能是内存中变量的地址 - 签名时不是因素。

  • 您可以为数字添加,减去或执行许多其他操作 将一个放在一个寄存器中,将另一个放在另一个寄存器中,使用ADDSUB指令,然后得到一个结果:

            MOV  EAX, 0x12345678
            MOV  EBX, 0x12345677
            SUB  EAX, EBX        ; EAX now holds the value 1
    
  • 您可以指向内存中的值。将变量的地址存储在寄存器中,您可以读取和写入这些值:

            .DATA
    xValue  DD   42       ; Save xValue here
    
            .CODE
            MOV  EAX, [xValue]         ; Get the current xValue into EAX
            INC  EAX                   ; Add one to it
            MOV  [xValue], EAX         ; Save it back
    
            INC  [xValue]              ; One line to do the above three
    
            MOV  EBX, OFFSET xValue    ; Point to xValue with EBX
            MOV  EAX, [EBX]            ; Get the current value
            INC  EAX                   ; Add one to it
            MOV  [EBX], EAX            ; Save it back
    
            INC DWORD PTR [EBX]        ; One line to do the above three
    
  • 如何传递字符串?
    你没有。您传递字符串的内存地址,接收函数只知道寄存器中的值是内存中字符串的地址。

  • 为什么你从堆栈中PUSHPOP

    • 只有有限数量的寄存器,因此需要将具有大量不同值的进程存储在内存中,将值交换进出寄存器以处理它们。
    • 您可以为每个变量使用保留的内存区域;或者您可以将值临时保存到堆栈中,而不是在内存中为它们保留特定位置。
    • 请注意,如果您有一个递归函数,那么保留内存区域将无法工作 - 每次通过递归时,您需要为下一次迭代创建新内存。堆栈非常适合这种情况。
    • 有些函数希望它们的参数存储在堆栈中,而不是存储在全局变量中。
  • 您如何知道使用哪个注册表?
    这取决于:

    • 如果您正在编写代码,则可以使用您喜欢的任何寄存器 - SP / ESP / RSP除外,它是为指向堆栈而保留的!
      • 有一些架构约定:
        • 如果您要使用REPLOOP说明,则需要使用CX / ECX / RCX来保留伯爵;
        • 如果您要使用LODSSTOSCMPSMOVS说明,则需要使用AL / { {1}} / AX / EAXRAX / SI / ESI和/或RSI / DI / { {1}}。
      • 有一些历史惯例,但在32位和64位编程中不再需要这些约定:
        • EDIRDIBXSI是唯一可以为内存编制索引的寄存器,因此它们的用途是什么;
    • 如果您没有编写您正在调用的代码,那么它应该指定(或使用通用标准)哪些寄存器保存哪些参数,以及它用于返回值的寄存器(一个或多个)。