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