[英]Why auxiliary flag is 0 when there is a borrow between nibbles
Testing on EMU8086, with the following code snippet:在 EMU8086 上进行测试,代码片段如下:
MOV CX, 1527H
SUB CX, 44H
The emulator shows that AF is 0模拟器显示AF为0
1527
- 44
========
14E3
When doing the subtraction by hand, we got 7 - 4 = 3, no problem here.手动减法时,我们得到 7 - 4 = 3,这里没问题。 Then 2 - 4, we then have to borrow from the next nibble.
然后 2 - 4,然后我们必须从下一个半字节借用。 So from my understanding, AF should have been 1.
所以根据我的理解,AF应该是1。
AF is set according to carry (or borrow) from bit #3 to bit #4. AF 根据从位#3 到位#4 的进位(或借位)设置。 ie across the lowest / least-significant nibble boundary, the one in the middle of AL/BL/CL/DL, not the middle of AX.
即跨越最低/最不重要的半字节边界,位于 AL/BL/CL/DL 中间的那个,而不是 AX 的中间。 (Since each hex digit represents a nibble, carry/borrow from the lowest hex digit into the 2nd-lowest.)
(由于每个十六进制数字代表一个半字节,因此从最低的十六进制数字进位/借位到第二低位。)
As you say 7h - 3h
doesn't borrow, so AF=0.正如你所说的
7h - 3h
不借,所以 AF=0。
The description of AF as a "half-carry" flag makes sense in the context of byte operand-size, where there's only one nibble boundary within the byte, and it's half-way to the carry-out position.将 AF 描述为“半进位”标志在字节操作数大小的上下文中是有意义的,其中字节内只有一个半字节边界,并且它是进位 position 的一半。
Word operand-size (and larger on 386 and x86-64) still sets AF from bit 3->4, not from the middle of the operand-size or carry between any other bit-positions.字操作数大小(在 386 和 x86-64 上更大)仍然从位 3->4 设置 AF,而不是从操作数大小的中间或任何其他位位置之间的进位。
That's because it's intended for packed and unpacked BCD operations like DAA and AAA respectively.这是因为它分别用于打包和解包 BCD 操作,如 DAA 和 AAA。 Note that AAA (for use after
add ax, cx
or whatever with 2 decimal digits unpacked into separate bytes) depends on AF detecting carry-out from the low 4 bits.请注意,AAA(用于在
add ax, cx
或将 2 个十进制数字解压缩到单独字节中的任何内容之后使用)取决于 AF 检测低 4 位的进位。 There would never be carry from bit #7 to bit #8 (across the byte boundary) in that case, eg 0x0909
+ 0x0909
produces 0x1212
, with an AF-setting carry from 9+9 = 12h
, but no carry from 09h + 09h = 12h
at the byte boundary.在这种情况下,从第 7 位到第 8 位(跨越字节边界)永远不会有进位,例如
0x0909
+ 0x0909
产生0x1212
,AF 设置进位来自9+9 = 12h
,但没有进位来自09h + 09h = 12h
在字节边界。
Instead of working differently for unpacked (checking the high bits of AL), AAA
uses mostly the same logic as for DAA (checking AF, and low nibble of al
being > 9) - https://www.felixcloutier.com/x86/aaa#operation AAA
使用与 DAA 大致相同的逻辑(检查 AF,并且al
的低半字节 > 9),而不是在解包时以不同的方式工作(检查 AL 的高位) - https://www.felixcloutier.com/x86/ aaa#操作
Fun fact: you can use DAS
to save a couple bytes in int -> ASCII-hex conversion , along with cmp and sbb, a total hack / abuse that just happens to work because of the distance between the ASCII codes for '9'
and 'A'
, along with DAS's conditional AL-=6
and other behaviour.有趣的事实:您可以使用
DAS
在 int -> ASCII-hex 转换中保存几个字节,以及 cmp 和 sbb,由于'9'
的 ASCII 码和'A'
,以及 DAS 的条件AL-=6
和其他行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.