汇编 - 如何处理寄存器
Assembly - How to handle registers
所以我正在努力学习汇编(NASM)。问题是组装的资源非常基础-理论和稀有,我无法理解非常基础的东西。我知道汇编寄存器在处理器的“内存”中用作“变量”。但问题是,例如在这个“hello world”类型的程序中:
section .text
global _start ;must be declared for linker (gcc)
_start: ;tell linker entry point
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello from assembly!',0xa ;a message
len equ $ - msg ;length of message
我无法理解为什么我们在 edx
上保存消息长度,在 ecx
上保存要写入的消息,例如 here 在 tutorialspoint 中它说:
所以这里我假设,因为 ECX 应该有循环计数器,在类 C 程序中:
for(int i = 0; i < 5; i++)
{
printf("Hey!\n");
}
ECX
寄存器应包含 i
。但是在上面的程序中,我们将消息保存在 ECX
.
同样,我很困惑,当我们想从汇编中调用C函数时,我们把参数保存在哪里,但我想,因为这是更高级的,如果我明白我保存在哪些寄存器中,我就会逐渐理解如果我想调用 C 函数会发生什么。
谢谢!
寄存器是独立的数据存储设备,因此将数据存储在何处并不重要,除非函数或指令要求您这样做。
在这种情况下,Linux系统调用要求将数据存储在特定的寄存器中。
在其他情况下,这些规则更像是良好做法:您应该遵循它们,但如果没有必要,您不一定非得这样做。
描述是一种反义词 - 试图追溯解释寄存器命名。它可能会帮助您记住寄存器的其他特殊用途,否则这些用途是通用的。但是,这并不是 真正 寄存器名称的原因。
Intel 处理器系列从 the 4004 开始,只有一个累加器,简称为寄存器 A。
后来的型号增加了更多的寄存器,A之后的下一个可能叫A2,也可能叫B。所以就变成了B。之后只有"natural"用C和D来换一个一对寄存器。现在我们在 8 位 CPU 上。
在将8086设计为16位器件时,将原来的8位寄存器A、B、C、D做成16位,命名为AX、BX、CX、DX。同时,它们比 8080 更通用。
因为它们 是 通用寄存器,所以除了它们的反义词名称所暗示的之外,它们还可以用于其他用途。例如,CX(或 ECX)可以很好地存储指向字符串的指针,而不是保存循环计数。
我曾经为此苦苦挣扎,但人们没有帮助。我刚刚被称为巨魔(srsly?)。
什么是寄存器?
寄存器是处理器拥有的一种简单的数据存储,它非常小(通常为 16、32 或 64 位)但非常快。
它们可用于将数据或地址存储到内存中。
所有不同的寄存器有什么意义?
1) 您不能使用一个寄存器来保存所有数据(除非您擅长混淆二进制内容)。
2)指令使用不同的寄存器(例如LOOP指令使用计数寄存器,即CX)
内存或硬盘怎么样?
数学之类的东西通常需要寄存器(也要吃蔬菜!)。内存比寄存器慢,你必须管理它。
这个例子可能会让您感到困惑,但它就像黄金和金钱。黄金没有经济,但它很有价值且稀有。很容易就能拿到钱,只是比较迷惑。
除非您需要访问文件,否则不应将硬盘用于 Assembly 的任何用途。
所以我正在努力学习汇编(NASM)。问题是组装的资源非常基础-理论和稀有,我无法理解非常基础的东西。我知道汇编寄存器在处理器的“内存”中用作“变量”。但问题是,例如在这个“hello world”类型的程序中:
section .text
global _start ;must be declared for linker (gcc)
_start: ;tell linker entry point
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db 'Hello from assembly!',0xa ;a message
len equ $ - msg ;length of message
我无法理解为什么我们在 edx
上保存消息长度,在 ecx
上保存要写入的消息,例如 here 在 tutorialspoint 中它说:
所以这里我假设,因为 ECX 应该有循环计数器,在类 C 程序中:
for(int i = 0; i < 5; i++)
{
printf("Hey!\n");
}
ECX
寄存器应包含 i
。但是在上面的程序中,我们将消息保存在 ECX
.
同样,我很困惑,当我们想从汇编中调用C函数时,我们把参数保存在哪里,但我想,因为这是更高级的,如果我明白我保存在哪些寄存器中,我就会逐渐理解如果我想调用 C 函数会发生什么。
谢谢!
寄存器是独立的数据存储设备,因此将数据存储在何处并不重要,除非函数或指令要求您这样做。
在这种情况下,Linux系统调用要求将数据存储在特定的寄存器中。 在其他情况下,这些规则更像是良好做法:您应该遵循它们,但如果没有必要,您不一定非得这样做。
描述是一种反义词 - 试图追溯解释寄存器命名。它可能会帮助您记住寄存器的其他特殊用途,否则这些用途是通用的。但是,这并不是 真正 寄存器名称的原因。
Intel 处理器系列从 the 4004 开始,只有一个累加器,简称为寄存器 A。
后来的型号增加了更多的寄存器,A之后的下一个可能叫A2,也可能叫B。所以就变成了B。之后只有"natural"用C和D来换一个一对寄存器。现在我们在 8 位 CPU 上。
在将8086设计为16位器件时,将原来的8位寄存器A、B、C、D做成16位,命名为AX、BX、CX、DX。同时,它们比 8080 更通用。
因为它们 是 通用寄存器,所以除了它们的反义词名称所暗示的之外,它们还可以用于其他用途。例如,CX(或 ECX)可以很好地存储指向字符串的指针,而不是保存循环计数。
我曾经为此苦苦挣扎,但人们没有帮助。我刚刚被称为巨魔(srsly?)。
什么是寄存器?
寄存器是处理器拥有的一种简单的数据存储,它非常小(通常为 16、32 或 64 位)但非常快。
它们可用于将数据或地址存储到内存中。
所有不同的寄存器有什么意义?
1) 您不能使用一个寄存器来保存所有数据(除非您擅长混淆二进制内容)。
2)指令使用不同的寄存器(例如LOOP指令使用计数寄存器,即CX)
内存或硬盘怎么样?
数学之类的东西通常需要寄存器(也要吃蔬菜!)。内存比寄存器慢,你必须管理它。
这个例子可能会让您感到困惑,但它就像黄金和金钱。黄金没有经济,但它很有价值且稀有。很容易就能拿到钱,只是比较迷惑。
除非您需要访问文件,否则不应将硬盘用于 Assembly 的任何用途。