我们正在使用有限的 8086 条指令学习汇编。
当我们在内存中有一个数组时,我们使用 SHL 在元素之间移动(取决于元素大小)。
例如,假设有一个 2 个字节的短裤数组。该数组位于 ES 段上,第一个元素从 BX 偏移量 (ES:[BX]) 开始。
如果我们想转到下一个元素,我们使用 SHL BX,1 ,然后使用 ES:[BX] 访问它。
ADD AX, ES:[BX]
SHL BX,1
ADD AX, ES:[BX]
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会这样,偏移量乘以 2。我们不应该将 2 添加到 BX 以转到下一个元素吗?
ADD AX, ES:[BX]
ADD BX,2
ADD AX, ES:[BX]
Run Code Online (Sandbox Code Playgroud)
左移是执行二进制乘法(即乘以 2 的幂)的一种有效方式,因此在编写汇编程序时常用。将一个值左移 1 等价于将值乘以 2 (2 1 == 2)。将值左移 2 等效于将值乘以 4 (2 2 == 4)。依此类推,遵循明显的模式。
还有其他位操作技巧可以有效地乘以 2 的非幂,但我不会在这里介绍这些技巧,因为它们有点复杂。要查看它们,请询问 C 编译器。
因此,您问题中的第一个代码块不正确。您不想将指针乘以 2。
正如您所说,访问数组中下一个值的方法是将指针增加元素的大小(以字节为单位)。对于 WORD 大小的数组,这意味着将指针增加 2,这是一条简单ADD指令可以执行的操作,如您所示:
ADD AX, ES:[BX]
ADD BX, 2
ADD AX, ES:[BX]
Run Code Online (Sandbox Code Playgroud)
假设这BX是指向数组第一个元素的指针,分配在ES段中,这将获得该元素的值并将其添加到AX. 然后,它将递增BX以指向数组的第二个元素,并将该地址处的值添加到AX。
在您可能更熟悉的 C 中,这等效于:
uint16_t* ptr = ...; // ES:[BX]
uint16_t result = ...; // AX
result += *ptr;
++ptr;
result += *ptr;
Run Code Online (Sandbox Code Playgroud)
请注意,C 会自动将指针增加其指向的值的大小。在这种情况下,由于ptr是指向 的指针uint16_t,它将地址加 2。
| 归档时间: |
|
| 查看次数: |
254 次 |
| 最近记录: |