汇编 - 如何处理寄存器

时间:2018-03-27 10:10:33

标签: assembly x86 nasm

所以我正在努力学习装配(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它说:

Description Of Registers

所以在这里我假设因为ECX应该有一个类似C的程序中的循环计数器:

for(int i = 0; i < 5; i++) 
{
      printf("Hey!\n");
}

ECX寄存器应包含i。但是在上面的程序中,我们将消息保存在ECX上。

同样地,当我们想要从汇编中调用C函数时,我很困惑我们保存参数的位置,但我认为因为这是更高级的,如果我理解我在哪些寄存器中保存了什么,逐渐地我会理解会发生什么以防我想调用C函数。

谢谢!

3 个答案:

答案 0 :(得分:1)

寄存器是独立的数据存储设备,因此除非函数或指令要求您这样做,否则存储数据并不重要。

在这种情况下,Linux系统调用需要将数据存储在特定寄存器中。 在其他情况下,这些规则应被视为更好的做法:您应该遵循它们,但如果没有必要,您不一定要这样做。

答案 1 :(得分:1)

这些描述是一种回溯 - 试图回溯地解释寄存器的命名。它可能会帮助您记住寄存器的其他特殊用途,否则这些用途是通用的。但是,它不是真正注册名称的原因。

英特尔处理器系​​列以the 4004开头,只有一个累加器,简称寄存器A.

当后来的模型添加了更多的寄存器时,A之后的下一个可能被称为A2或者可能是B.所以它恰好成为B.之后它只是&#34;自然&#34;将C和D用于另一对寄存器。现在我们使用的是8位CPU。

当将8086设计为16位器件时,旧的8位寄存器A,B,C和D为16位,并命名为AX,BX,CX和DX。而且,与此同时,它们比8080更具通用性。

由于它们通用寄存器,因此它们可以用于除了它们的backronym名称之外的其他内容。例如,CX(或ECX)可以很好地存储指向字符串的指针,而不是保持循环计数。

答案 2 :(得分:0)

我曾经一直在努力,人们没有帮助。我刚被称为巨魔(srsly?)。

什么是注册?

寄存器是处理器具有的非常小的数据存储(通常为16,32或64位),但速度非常快。

它们可用于将数据或地址存储到内存中。

所有不同寄存器的重点是什么?

1)您不能使用一个寄存器来保存所有数据(除非您对混淆二进制文件很好)。

2)指令使用不同的寄存器(例如,LOOP指令使用计数寄存器,即CX)。

内存或硬盘怎么样?

数学等课程通常需要寄存器(也要吃蔬菜!)。内存比寄存器慢,你必须管理它。

这个例子可能让你感到困惑,但它就像黄金和金钱一样。黄金没有经济,但它是有价值和罕见的。你可以很容易地获得金钱,但它的工作原理却更加令人困惑。

除非您需要访问文件,否则不应将硬盘驱动器用于任何装配体。