2016-04-28 132 views
0

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

但是,我一直得到一个浮点错误,我不知道它来自哪里。

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 

预先感谢您

+0

出于好奇,一年后的“,10,0”是什么? –

+1

'cwd'不会做你认为它做的事。您应该简单地将'rdx'归零。正如Matti所说,不要跳入数据:) – Jester

+0

@MattiVirkkunen在印象之下,完成一个“db”语句是必要的 – Jeremy

回答

0

中,只有在整数的交易通常是由不正确的分割造成了程序的浮点错误。在你的情况下,它看起来并不像零分,所以它将成为迈克尔佩奇在评论中指出的分裂溢出。

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

简单地执行数据不会使计算机打印它。您需要进行系统调用才能打印出字符串。要做到这一点的方法是依赖于平台的。

+0

DIV指令有两个一般的整数除法错误原因。 Div除零,以及除法溢出,商不能在目标寄存器中表示。通常情况下,人们使用DIV并且不会将DX/EDX/RDX寄存器清零。在这种情况下'xor edx,edx'将被保证为未签名的分割。 –

+1

哦,我不知道溢出会导致同样的错误。那么这就是问题的分歧。在修复之后,它会立即通过尝试执行数据而崩溃。 –