Assembly 浮点异常程序集64位
浮点异常核心已转储。我使用的是64位汇编。我认为我在使用div指令时得到了错误,这是我所看到的错误,(人们似乎在不清除RDX时得到了它),但当我用xor函数清除它时,我不知道我的代码有什么问题Assembly 浮点异常程序集64位,assembly,x86-64,floating-point-exceptions,Assembly,X86 64,Floating Point Exceptions,浮点异常核心已转储。我使用的是64位汇编。我认为我在使用div指令时得到了错误,这是我所看到的错误,(人们似乎在不清除RDX时得到了它),但当我用xor函数清除它时,我不知道我的代码有什么问题 section .text global _start ;must be declared for linker (ld) _start: mov rdi,1 ;
section .text
global _start ;must be declared for linker (ld)
_start:
mov rdi,1 ;tell linker entry point
mov rax,rdi
push rax
jmp loop
loop:
pop rax
cmp rax,19
jle test3
mov rax,1;quit
syscall ;quit
test3:
add rdi,1
push rdi
mov rax,rdi
xor rdx,rdx
mov rbx,3
div rbx
cmp rdx,0
je fizz
jmp test5
test5:
mov rax,rdi
xor rdx,rdx
mov rbx,5
div rbx
cmp rdx,0
je buzz
jmp loop
fizz:
mov rdx,5 ;message length
mov rcx,msg ;message to write
mov rbx,1 ;file descriptor (stdout)
mov rax,4 ;system call number (sys_write)
syscall ;call kernel
jmp loop
buzz:
mov rdx,5 ;message length
mov rcx,msg2 ;message to write
mov rbx,1 ;file descriptor (stdout)
mov rax,4 ;system call number (sys_write)
syscall ;call kernel
jmp loop
section .data
msg db 'fizz',10
msg2 db 'buzz',10
您的程序生成错误的
syscall
s
在System V ABI中,系统调用的参数位于以下寄存器中:
rdi
,rsi
,rdx
,rcx
,r8
,r9
另外,1
用于sys\u write
,4
用于sys\u stat
(sys\u exit
为60
)
浮点异常仅在除数为0
或未清除rdx
时发生。既然两种情况都不是这样,那就不应该发生
section .text
global _start ;must be declared for linker (ld)
_start:
mov r8,1 ;tell linker entry point
mov rax,r8; rdi is needed for syscalls, have to use another register
; or save it before preparing to call the kernel
push rax
jmp loop
loop:
pop rax
cmp rax,19
jle test3
mov rax, 60; sys_exit
xor rdi, rdi; clear rdi(exit code)
syscall
test3:
add r8,1
push r8
mov rax,r8
xor rdx,rdx
mov rbx,3
div rbx
cmp rdx,0
je fizz
jmp test5
test5:
mov rax,r8
xor rdx,rdx
mov rbx,5
div rbx
cmp rdx,0
je buzz
jmp loop
fizz:
mov rdx,5 ;message length
mov rsi,msg ;message to write
mov rdi,1 ;file descriptor (stdout)
mov rax,1 ;system call number (sys_write)
syscall ;call kernel
jmp loop
buzz:
mov rdx,5 ;message length
mov rsi,msg2 ;message to write
mov rdi,1 ;file descriptor (stdout)
mov rax,1 ;system call number (sys_write)
syscall ;call kernel
jmp loop
section .data
msg db 'fizz',10
msg2 db 'buzz',10
输出为:
fizz
buzz
fizz
fizz
buzz
fizz
fizz
fizz
buzz
您可以在此表中找到syscall
编号:
是的,
#DE
是x86 Linux上获取SIGFPE算术异常信号的唯一方法,除非您取消某些实际FP异常的掩码。哪个div
指令故障?使用调试器来查找。另外,您是如何组装+链接并运行此程序的?您确定在更改源代码后重新生成了可执行文件吗?我在我的Linux桌面上尝试了这个,它只是进入了一个无限循环,没有打印任何东西。(您的代码看起来过于复杂,所以我没有亲自调试无限循环,例如je
/jmp
很愚蠢,只需使用jne
或fall-through;另外,像dec ebx/jz fizz
这样的下行计数器会更有效)。(我使用nasm-felf64 fizzbuzz.asm
组装,并直接使用ld-o fizzbuzz fizzbuzz.o
链接到一个静态可执行文件中)。所以这不是你要问的问题,我用的是nasm。在ubuntu终端上编译并运行itI,我现在得到了相同的结果,无限循环,什么也不打印。为什么代码没有结束?一旦rdi等于20,就应该使用调试器单步执行并找出答案。IDK为什么使用push/pop;那看起来很奇怪。哦,顺便说一句,你对syscall参数使用了错误的寄存器;这就是为什么他们总是返回-EFAULT
(使用strace
)。您使用的是32位呼叫号码和寄存器,而不是64位。普通的fizzbuzz也会打印出不是3或5的倍数的号码。请参阅(或递增ASCII数字)。OP的代码甚至不尝试这样做,所以yes+1表示OP的代码正常工作。(尽管它仍然非常低效和笨重。例如,有一个jmp test5
,这是一个不可操作的测试;无论如何执行都会失败。而且fizz
和buzz
块中的大多数指令都是相同的。)