【问题标题】:Linux Intel 64bit Assembly DivisionLinux Intel 64位组装事业部
【发布时间】:2015-08-21 11:42:46
【问题描述】:

我正在努力理解为什么我的除法不起作用,下面是我当前的代码,它只需要两个个位数并尝试将它们除:

STDIN equ 0
SYS_READ equ 0

STDOUT equ 1
SYS_WRITE equ 1

segment .data
    num1 dq 0
    num2 dq 0
    quot dq 0
    rem dq 0

segment .text
    global _start
_start:
    mov rax, SYS_READ
    mov rdi, STDIN
    mov rsi, num1
    mov rdx, 2
    syscall

    mov rax, SYS_READ
    mov rdi, STDIN
    mov rsi, num2
    mov rdx, 2
    syscall

    mov rax, [num1]
    sub rax, '0'

    mov rbx, [num2]
    sub rbx, '0'

    xor rdx, rdx
    div rbx

    add rax, '0'

    mov [quot], rax
    mov [rem], rdx

    mov rax, SYS_WRITE
    mov rdi, STDOUT
    mov rsi, quot
    mov rdx, 1
    syscall

    mov rax, 60
    xor rdi, rdi
    syscall

现在据我了解,当划分汇编程序时,RDX:RAX 除以操作数 RBX。我只能假设这是问题所在,事实上我将 128 位值除以 64 位值。每当我输入诸如 8 / 2 或类似的东西时,我都会收到值 1 作为商。我在这里想念什么?任何帮助将不胜感激。

【问题讨论】:

  • 像往常一样,学习使用调试器。

标签: linux assembly 64-bit intel division


【解决方案1】:

您为操作数读取了 2 个字节,但您似乎忽略了第 2 个字节,而实际上您不应该这样做。
假设您键入 8 和 2 各一行,您将阅读“8\n”和“2\n”。然后减去'0',但留下'\n',所以你的操作数将是0x08 0x0A0x02 0x0A,它们是2568和2562。而2568 / 2562 = 1。

【讨论】:

  • 一个可能的解决方案是使用movzx rax, byte [num1] 和类似的num2
  • 非常感谢。这解决了我的问题。我一直想知道那条额外的新线发生了什么。每当我使用 add 或 sub 时,它都能正常工作,所以我(错误地)认为它只是消失了。感谢@Jester 提供的解决方案,是的,我现在正忙着学习如何使用 GDB。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 2012-03-19
  • 2010-11-29
  • 2015-06-26
  • 2015-01-05
相关资源
最近更新 更多