简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM