IDIVQ指令工作异常。 。 。 16 mod 100 = 0?

时间:2019-05-21 12:59:09

标签: assembly x86-64

我想用汇编语言x86-64检查1〜1000除以100的模值。

问题是'IDIVQ'指令工作异常,我不明白为什么。

这是我的代码


.L0:
  ##dividend in %rax
  ##divider in %rsi
  ##modulo in %rdx

  pushq   %rax      # store dividend
  movq  $0x00, %rdx # initialize %rdx
  idivq   %rsi      # divide %rax by %rsi , modulo in  %rdx
  cmpq  $0x00, %rdx # if divided
  je   .L1


.L1:
  popq %rax   # retrieve dividend
  inc  %rax   # increment
  'When dividend == 1000, return'
  jmp  .L0


在GDB上就像


(gdb) p $rax
$7 = 16
(gdb) p $rsi
$8 = 100
(gdb) step
77    idivq   %rsi        # divide %rax by %rsi , modulo in  %rdx
(gdb) step
78    cmpq  $0x00, %rdx # if divided
(gdb) p $rsi
$9 = 100
(gdb) p/x $rax
$11 = 0x28f5c28f5c28f5c
(gdb) p $rdx
$12 = 0

有人给我提示为什么会这样吗?

就目前而言,我知道初始化%rdx很重要。 当我这样做

movq $0x01, %rdx
idivq %rsi

结果改变了,但是完全不正确,因为它们与正确答案都相距1

我放的时候

movq $0x1000, %rdx
idivq %rsi

导致细分错误。

1 个答案:

答案 0 :(得分:2)

您没有运行所显示的代码或cpu损坏(不太可能)。

7     idivq   %rsi      # divide %rax by %rsi , modulo in  %rdx
(gdb) p $rax
$1 = 16
(gdb) p $rsi
$2 = 100
(gdb) si
8     cmpq  $0x00, %rdx # if divided
(gdb) p $rax
$3 = 0
(gdb) p $rdx
$4 = 16

是的,您需要将rdx设为零,因为那是红利的高64位。