Assembly 64位nasm除法idiv

Assembly 64位nasm除法idiv,assembly,x86-64,nasm,Assembly,X86 64,Nasm,我似乎不明白为什么这不是除法,我得到了一个“浮点异常”,我使用的是64位机器,值是整数而不是浮点。。。。想法 我知道除法后,商应该是rax,余数应该是rdx,我相信,但现在我只是想得到商。你实际上是把rdx:rax中的128位数字除以RCX。因此,如果RDX未初始化,结果可能会大于64位,从而导致溢出异常。尝试在分区之前添加一个CQO,以将extend RAX签名为RDX 不过,我无法解释浮点位,也许有人决定在某个地方重用中断向量来处理一般数学错误?我觉得你的函数有点复杂idiv使用此功能可按预

我似乎不明白为什么这不是除法,我得到了一个“浮点异常”,我使用的是64位机器,值是整数而不是浮点。。。。想法


我知道除法后,商应该是rax,余数应该是rdx,我相信,但现在我只是想得到商。

你实际上是把rdx:rax中的128位数字除以RCX。因此,如果RDX未初始化,结果可能会大于64位,从而导致溢出异常。尝试在分区之前添加一个CQO,以将extend RAX签名为RDX


不过,我无法解释浮点位,也许有人决定在某个地方重用中断向量来处理一般数学错误?

我觉得你的函数有点复杂
idiv
使用此功能可按预期工作:

;print out division message
mov rcx, 0                       ;zero out register
mov rax, [input]
mov rcx, [input2]
idiv rcx                        ;divide rax by rcx
mov rdi, rax                    ;for printing purposes
call print_int
翻译成NASM语法和windows ABI,我认为应该是这样的:

_mydiv:
  xor  %rdx, %rdx ; clear high bits of dividend
  mov  %rdi, %rax ; copy dividend argument into rax
  idiv %rsi       ; divide by divisor argument
  ret             ; return (quotient is in rax)
你是不是一路踩着你的参数,弄糊涂了

编辑:看着你的代码,我突然想到它可能根本就不是一个正确的函数。重要的步骤是:

  • 将红利放在RDX:RAX中——对您来说,这可能意味着清除RDX并将输入红利放在RAX中
  • 把除数放在另一个寄存器中——你们选择了RCX,那个应该没问题
  • 除法-
    idiv rcx
  • 结果将是RAX

  • 您应该特别注意第1步-确保RDX:RAX有健全的内容!为什么会出现浮点异常,我无法从您显示的代码中猜出来。

    就是这样,指导步骤帮助很大,我之前没有清除rdx寄存器,非常感谢!!!为什么在nasm中使用r8?有必要吗?@Nande,不是NASM,而是windows abi的正确版本,其中rdx是一个参数传递寄存器。可能的副本供将来参考,在哪里可以找到类似
    cqo
    的指令?在GAS语法中,它是
    cqto
    ,在MASM语法中它应该转换成什么似乎并不清楚。@Vortico:总是一个好的开始。特别是对于CQO,我承认我不知道128位单词的正确后缀,但我必须查找CBW/CWD/CDQ,看看64位的等价物可能被称为什么
    _mydiv:
      mov  r8, rdx    ; copy divisor argument to scratch register
      xor  rdx, rdx   ; clear high bits of dividend
      mov  rax, rcx   ; copy dividend argument into rax
      idiv r8         ; divide by divisor in scratch register
      ret             ; return (quotient is in rax)