当半字节之间有借位时,为什么辅助标志为 0

问题描述

在 EMU8086 上进行测试,代码片段如下:

MOV CX,1527H
SUB CX,44H

模拟器显示AF为0

   1527
 -   44
========
   14E3

手动减法时,我们得到 7 - 4 = 3,这里没问题。 然后是 2 - 4,然后我们必须从下一个半字节借用。所以根据我的理解,AF 应该是 1。

解决方法

AF 根据从位 #3 到位 #4 的进位(或借位)设置。即跨越最低/最不重要的半字节边界,即 AL/BL/CL/DL 中间的边界,而不是 AX 的中间。 (因为每个十六进制数字代表一个半字节,从最低的十六进制数字进位/借入到第二个最低的。)

正如你所说的 7h - 3h 不借,所以 AF=0。

将 AF 描述为“半进位”标志在字节操作数大小的上下文中是有意义的,其中字节内只有一个半字节边界,并且它位于进位位置的一半。>

字操作数大小(在 386 和 x86-64 上更大)仍然从位 3->4 设置 AF,而不是从操作数大小的中间或任何其他位位置之间的进位。


那是因为它分别用于打包和解包 BCD 操作,如 DAA 和 AAA。请注意,AAA(用于在 add ax,cx 之后或将 2 个十进制数字解压缩到单独字节中的任何内容)取决于 AF 检测低 4 位的进位。在这种情况下,永远不会有从第 7 位到第 8 位(跨字节边界)的进位,例如0x0909 + 0x0909 产生 0x1212,带有来自 9+9 = 12h 的 AF 设置进位,但在字节边界处没有来自 09h + 09h = 12h 的进位。

与解包(检查 AL 的高位)不同,AAA 使用与 DAA 大致相同的逻辑(检查 AF,并且 al 的低半字节 > 9) - { {3}}

有趣的事实:你可以https://www.felixcloutier.com/x86/aaa#operation,连同 cmp 和 sbb,一个完全的黑客/滥用,恰好因为 '9''A' 的 ASCII 代码之间的距离而起作用,以及 DAS 的条件 AL-=6 和其他行为。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...