【问题标题】:Leap-year NASM Assembly program闰年 NASM 装配计划
【发布时间】:2016-04-28 00:26:15
【问题描述】:

我目前正在使用 NASM elf64 x64 构建一个汇编程序,它将判断输入的年份是否为闰年。目前,我将年份硬编码为 1986 年,但在最终版本中,它应该采用命令行参数。

但是。我不断收到一个浮点错误,我无法弄清楚它来自哪里。

    global main
    extern puts
    section .text

main:
    mov rax, year
    cwd
    mov rcx, 400
    div rcx
    test rdx, rdx
    jz _is_leap

    mov rax, year
    cwd
    mov rcx, 100
    div rcx
    test rdx, rdx
    jz _no_leap

    mov rax, year
    test rax, 3
    jz _is_leap

 year
    dq      1986, 10, 0      


 _no_leap:
    db      "This is NOT a leap year", 10, 0            ;print out is not a leap year
    jmp _after

 _is_leap:
    db      "This is a leap year", 10, 0            ;print is a leap year
    jmp _after

 _after:
    ret

提前谢谢你

【问题讨论】:

  • 只是出于好奇,一年后的“, 10, 0”是什么意思?
  • cwd 不会像您认为的那样做。你应该简单地将rdx 归零。正如马蒂所说,不要跳入数据:)
  • @MattiVirkkunen 的印象是这些是完成“db”语句所必需的
  • 不,您不需要随机幻数来“完成”数据声明。通常在字符串之后看到它们,因为它们代表换行符和用于终止字符串的空字节,这在将它们传递给期望以空终止字符串的函数时很有用。
  • 您可能需要查看您的classmates code 以了解如何使用puts 打印字符串。

标签: assembly nasm elf


【解决方案1】:

仅处理整数的程序中的浮点错误通常是由不正确的除法引起的。在您的情况下,它看起来不像被零除,因此正如 Michael Petch 在 cmets 中指出的那样,它将是除法溢出。

一个更大的问题是,您正在跳转到一个不包含有效代码的位置。例如,您的_no_leap 位置包含表示字符串“这不是闰年\n\0”的字节,并且您告诉系统将其解释为代码。那是行不通的。

仅仅执行数据不会让计算机打印它。您需要进行系统调用以打印出字符串。实现这一点的方法取决于平台。

【讨论】:

  • DIV 指令出现整数除法错误的一般原因有两个。除以零,除法溢出,商无法在目标寄存器中表示。当人们进行 DIV 并且不将 DX/EDX/RDX 寄存器归零时,通常会出现这种情况。在这种情况下,xor edx, edx 将被保证为无符号除法。
  • 哦,我不知道溢出会导致同样的错误。那么问题就出在分工上。修复后,它会通过尝试执行数据立即崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2016-01-01
相关资源
最近更新 更多