Assembly 在汇编x86中,寄存器和堆栈的大小真正意味着什么

Assembly 在汇编x86中,寄存器和堆栈的大小真正意味着什么,assembly,x86,Assembly,X86,我是汇编新手,我真的很困惑,我读了好几篇文章和书,但我不明白这意味着什么 在汇编x86中,我们有不同的寄存器,每个寄存器都有特定的大小,例如 EAX:32位 Q1-那么32位的真正含义是什么?这是否意味着我只能存储32位大小的值? 如果有的话 Q2-如果我有很长的字符串,如何将该字符串移动到寄存器? Q3-我想知道我应该在什么时候从堆栈中推出来? Q4我可以在没有堆栈的情况下将值存储在寄存器中,为什么我们有堆栈?要解决哪个问题? 如果我们以我的C代码为例: #include<stdio.h

我是汇编新手,我真的很困惑,我读了好几篇文章和书,但我不明白这意味着什么

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

EAX:32位

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

如果有的话

Q2-如果我有很长的字符串,如何将该字符串移动到寄存器?

Q3-我想知道我应该在什么时候从堆栈中推出来?

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

如果我们以我的C代码为例:

#include<stdio.h>

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

}
#包括
main()
{
printf(“你好世界”);
}
在这里,我们将helloworld传递给printf函数,我可以传递任何大的或小的东西,不管是什么,如果我将代码翻译成汇编,首先我必须将系统调用args移动到寄存器,然后调用系统调用,然后调用int 0x80。如果helloworld的instate有一段话呢

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


谢谢。

注册门店号。就这样。他们就这么做。这是作为程序员,你如何使用和解释这些数字,使程序工作

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

  • 您可以对数字进行加法、减法或其他许多操作。
    将一个放入一个寄存器,另一个放入另一个寄存器,使用
    ADD
    SUB
    指令,您将得到一个结果:

            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
    
  • 如何传递字符串?
    你没有。传递字符串的内存地址,接收函数只知道寄存器中的值是内存中字符串的地址

  • 为什么要从堆栈中
    弹出

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

    • 如果您正在编写代码,您可以使用任何您喜欢的寄存器-除了
      SP
      /
      ESP
      /
      RSP
      ,它是为指向堆栈而保留的!
      • 有一些架构约定:
        • 如果要使用
          REP
          LOOP
          指令,则需要使用
          CX
          /
          ECX
          /
          RCX
          来保持计数
        • 如果要使用
          LODS
          STOS
          CMPS
          MOVS
          指令,则需要使用
          AL
          /
          AX
          /
          EAX
          /
          RAX
          SI
          /
          ESI
          /
          RSI
          和/或
          DI
          /
          EDI
      • 有一些历史约定,但在32位和64位编程中不再需要这些约定:
        • BX
          SI
          DI
          BP
          是唯一可以索引内存的寄存器,所以它们就是用来索引内存的
    • 如果您没有编写要调用的代码,那么它应该指定(或使用公共标准)哪些寄存器保存哪些参数,以及它使用哪些寄存器作为返回值

注册存储编号。就这样。他们就是这么做的。这是作为程序员,你如何使用和解释这些数字,使程序工作

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

  • 您可以对数字进行加法、减法或其他许多操作。
    将一个放入一个寄存器,另一个放入另一个寄存器,使用
    ADD
    SUB
    指令,您将得到一个结果:

            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
    
  • 如何传递字符串?
    你没有。传递字符串的内存地址,接收函数只知道寄存器中的值是内存中字符串的地址

  • 为什么要从堆栈中
    弹出

    • 寄存器的数量有限,因此要处理具有许多不同值的进程,需要在内存中存储一些值,在寄存器中交换值以处理它们
    • 您可以为每个变量使用保留的内存区域;或者,您可以将值临时保存到堆栈中,而不是在内存中为它们保留特定位置
    • 请注意,如果您有一个re