assembly - 关于初始化寄存器

标签 assembly x86-16 cpu-registers

我是汇编语言编程新手,正在开发 dosbox 应用程序。

我的问题是,当我们用汇编语言编写任何程序时,是否必须像在 C# 编程中初始化变量一样初始化通用寄存器?

我们可以将 AL 中的 ax 寄存器初始化为:

mov ax,0?

最佳答案

mov ax, 1234 的工作不依赖于旧值,就像在 C# 中一样,您可以编写 x = 1234 赋值,而无需先将其归零。

寄存器永远存在,它并不完全像int foo = 1234那样创建一个新的存储位置,但是将第一次写入寄存器视为初始化您正在使用的局部变量会很有帮助。 使用该寄存器来保存。

每条指令对架构状态(寄存器和内存内容)都有固定的影响,就像状态机一样。你是如何达到目前的状态并不重要;重要的是。 mov ax, 1234 的效果总是覆盖 ax 的先前值,因此它保存 1234,又名0x04d2,又名表示这两个数字的二进制位模式。

如果您想对数组求和,可以在使用 add ax, [si]/add si,2 的循环之前 mov ax, 0 ,因为这是实现与 C int sum=0; 相同逻辑的一种方法; for(...) { sum += *p; p++;} 初始化为零只是,因为我们想要使用依赖于旧值1的指令,如add .


脚注 1:如果您要优化代码大小,则可以使用 lodsw添加 dx, ax,因为 lodsw 会增加 si 乘 2。当然,您总是会使用 xor eax,eax 而不是 mov ax,0 将 AX 归零:不管表面如何,CPU特殊情况是微架构上的清零习惯对寄存器的旧值有输入依赖性。

对于xor ax,ax则不然;这只节省了代码大小,但不会将整个寄存器清零,因此现代 CPU 不会出现特殊情况。但如果您正在为 386 之前的 CPU 进行编程,那么无论如何您都只需使用 xor ax,ax 即可;它不会执行无序执行,输入依赖项无关紧要:无论值如何,x ^ x 始终为零。


do we have to initialise the general purpose registers as we use to initialise the variables in C# programming?

几乎是的; asm 中的寄存器只需要与高级语言中的变量一样多的初始化:在第一次读取之前至少一次,除非它们是传入函数参数。

首次使用为只写的 C/C++/C# 变量在声明时不需要进行初始化。 (尽管在现代 C++ 和 C# 风格中,您通常要等到第一个赋值才声明它们。)

您可以将寄存器视为一些局部变量的有限空间,和/或用于计算临时变量的暂存空间。

正如 Michael Petch 评论的那样,您不使用的寄存器可以保持不变。

关于assembly - 关于初始化寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59017138/

相关文章:

linux - 在适用于 Linux 的 Windows 子系统上的 Ubuntu 上使用 INT 0x80 汇编编译的可执行文件不产生输出

c - 为什么编译器要在栈上腾出空间

assembly - 更改 IRQ8 ISR

assembly - 如果我在程序中使用 fsin 来查找值的 sin,我会发现表达式语法错误

performance - ARM 程序集 : Absolute Value Function: Are two or three lines faster?

assembly - 为什么CMP(比较)有时会在8086组件中设置进位标志?

assembly - 为什么 x86 寄存器如此命名?

nasm - ORG指令后设置段寄存器

c - 为什么无法使用循环访问寄存器数组

assembly - %pcrel_hi 和 %pcrel_lo 实际上做了什么?