gpt4 book ai didi

assembly - 从内存中添加一个字节到 AX 寄存器

转载 作者:行者123 更新时间:2023-12-04 07:25:02 30 4
gpt4 key购买 nike

我目前正在尝试弄清楚如何将指针寄存器 SI 指向的内存中的第一个字节添加到 AX 寄存器的当前内容中。

因此,如果 SI 包含某个地址,并且该地址在内存中的值是:00 和 01,我希望将 00 添加到 AX 寄存器.

我的汇编菜鸟自己尝试的第一个指令是 add ax, byte ptr [SI] 但当然,没有骰子,因为我正在尝试添加不同大小的操作数。

我目前的解决方法是

mov dx,0000h             ;empty the contents of dx
mov dl,byte ptr [si] ;get the value of the first byte in a register
add ax,dx ;perform the originally desired addition

但这是非常浪费的,并且确实损害了我执行的指令数(这是运行多次的子例程的一部分)。

我仅限于 8086 指令集,所以 this question/answer by Peter Cordes不幸的是,这表明 movzx 压缩我的前两行是不可行的。

最佳答案

正如您所说,如果您可以假设一个 386 兼容的 CPU,一个不错的选择(尤其是对于现代 CPU)是 movzx dx, byte ptr [mem]/add ax, dx 。如果不是,我想我们可以假装我们正在调整一个真正的 8086,where code size in bytes is often more important than instruction count . (特别是在 8088 上,它的 8 位总线。)所以你肯定想使用 xor dx, dx 来将 DX 归零(2 字节而不是 3 for mov reg, imm16),如果您无法完全避免归零指令。

将 DX(或 DH)的归零提升到任何循环之外,因此您只需 mov dl, [mem]/add ax, dx。如果函数只执行一次,您可能需要(手动)将函数内联在循环调用它的调用站点中,如果它足够小以至于有意义的话。或者选择一个调用者负责将上半部分设为零的寄存器。

正如 Raymond 所说,您可以选择任何其他寄存器,您知道其高半部分在函数的那个​​点为零。也许你可以 mov cx, 4 而不是 mov cl, 4 如果你之前碰巧需要 CL=4 来做其他事情,但到那时你已经完成了 CX你需要添加到 AX 中。 mov cx, 4 仅长 1 个字节,因此您只需增加 1 个字节的代码大小即可将 CH 清零。 (相对于 xor cx, cx 花费 2 个字节)


另一个选项是字节添加/adc,但这对于代码大小来说并不理想。 (或在更高版本的 CPU 上的性能。)

  add al, [mem]      ; 2 bytes + extra depending on addr mode
adc ah, 0 ; 3 bytes

所以这比你已经有一个备用的上零寄存器多了 1 个字节:

  mov  dl, [mem]     ; 2 bytes (+ optional displacement)
add ax, dx ; 2 bytes

但从好的方面来说,add/adc 根本不需要任何额外的寄存器。


有了 SI 中的指针,如果您真的要优化代码大小,就值得寻找利用 lodsb 的方法。这会执行 mov al, [si]/inc si(如果 DF=1,则改为 dec si),但不会影响 FLAGS。所以你想添加到不同的寄存器中。

xchg ax, reg 只有 1 个字节,但如果您需要两次交换,如果您实际上必须返回 AX,而不是其他寄存器,它可能无法收回成本。

关于assembly - 从内存中添加一个字节到 AX 寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68263286/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com