【问题标题】:Decrementing ax递减斧头
【发布时间】:2016-10-09 00:53:27
【问题描述】:

我想知道是否有人可以解释为什么它从 0000 变为 FFFF。

执行以下行后,EAX 中的值是多少?

mov  eax,30020000h
dec  ax

eax中的值改为3001FFFFh 为什么会翻转?

【问题讨论】:

  • AX 是 EAX 寄存器的低 16 位。那么 EAX 的低 16 位是什么? 0000 .因此,当您执行dec ax 时,它不会影响 EAX 的高 16 位,因此从 AX 中减去 1 是 FFFF。高位保持不变。我不同意结果是 3001FFFF 。我认为应该是 3002FFFF。
  • 你认为它可能会减少 AX(所以 AH 和 AL)而不仅仅是寄存器的 AL 部分? @MichaelPetch
  • 请参阅Understanding Carry vs. Overflow conditions/flags,了解二进制数学中的环绕。
  • 您是否将二进制与十六进制混为一谈? 11h 是 00010001b。在 0 - 1 之后,AL 中的实际结果将是 11111111b。
  • 这就是我要说的。我认为您将二进制与十六进制混合在一起。去阅读teaching.idallen.com/dat2343/10f/notes/040_overflow.txt,它有二进制示例。请记住,二进制的 1111 是十六进制的 F。

标签: assembly x86 cpu-registers


【解决方案1】:

eax中的值改为3001FFFFh为什么会翻转?

eax 的值为 3002FFFFh。

初始指令将 30020000h 复制到 EAX。这将设置 EAX 的所有 32 位。

第二条指令只影响 EAX 的低 16 位,也称为 AX。任何带有 AX 的指令都只会影响那些位,所以你要递减 0000h。您的进位标志也将被设置。我认为,这里有一些有用的方法来思考这个问题。

1- 当你增加它时,什么数字会给你 0000h? FFFFh 符合条件,因为如果您要添加一个,它将使最右边的 F 变为 0,并且该 F 将携带到下一个,等等。您的答案将是 10000h,它不适合 16 位,留下您的 16 位作为 0000h。

2- 要减去这个问题,您需要借用。

0000h  
  -1h  

你总是可以借用这种数学。你只需要设置“carry”标志来表明你这样做了!使用这个技巧,你真的有:

10000h  
   -1h  

现在答案很明显是 FFFFh,进位标志将被设置。

3- 这个数学实际上只是模 2 的幂(寄存器大小)。这意味着您可以画出数字轮而不是数字轴。像 AX 这样的 16 位寄存器有 2^16 = 65536 种可能的组合,你可以写成 0000h、0001h、0002h...FFFEh、FFFFh、0000h 等。就像从 0000h 递增到 0001h 一样,递减到 FFFFh等。

4- 手动进行二进制补码。当您递减时,您正在添加负数。

Start with 
  "1" =  0001h  
Invert the bits:  
     FFFEh  
Add one:  
Now you have the two's complement:
  "-1" = FFFFh   

然后您将二进制补码 (FFFFh) 添加到您尝试递减的数字 (0000h) 上,并得到 FFFFh。

但你的问题说你得到 3001FFFFh。再次检查:你没有。它是 3002FFFFh。如果你减少 eax,而不是 ax,你只会得到 3001FFFFh。在这种情况下,你会从“2”中借来得到你的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    相关资源
    最近更新 更多