【发布时间】:2020-02-17 20:43:36
【问题描述】:
我有以下代码:
extern printf
section .data
A db 1
B db 2
C db 3
D db 4
E db 5
fmt db "%d",10,0
fmt2 db "An overflow has occured",10,0
section .text
global _start
_start:
xor rax, rax
xor rbx, rbx
xor rdx, rdx
xor ax, ax
mov al, [B]
mul ax
jo over
call printax
mov bx, ax
xor ax, ax
mov al, [C]
mul ax
jo over
call printax
xor cx, cx
mov cl, [C]
mul cx
jo over
call printax
xor cx, cx
mov cl, [E]
div cx
jo over
call printax
xor dx, dx
xor al, al
mov rdi, fmt
call printf
jmp exit
over:
mov rdi, fmt2
xor al, al
call printf
exit:
mov rax, 60
mov rdi, 0
syscall
printbx:
xor rsi, rsi
mov si, bx
mov cl, al
xor al, al
mov rdi, fmt
call printf
mov al, cl
xor si, si
ret
printax:
xor rsi, rsi
mov si, ax
xor al, al
mov rdi, fmt
call printf
mov ax, si
xor si, si
ret
我使用nasm -f elf64 1.asm 编译它并使用ld -dynamic-linker /lib/ld-linux-x86-64.so.2 1.o -o 1 -lc 链接它。当我执行二进制文件时,我得到了
$ ./1
4
9
0
Floating point exception (core dumped)
当我在汇编代码中调用printf() 时,它并不总是失败。
从printax 和printbx 中删除printf() 调用给了我
$ ./1
0
更新:如果我删除 div cx 行,异常也会消失。然后我得到以下输出:
$./1
4
9
0
0
0
但即使我添加它也不会消失
mov cx, 1
mov ax, 1
在div cx 之前。
【问题讨论】:
-
这里唯一可能导致 FPE 的行是
div bx -
哇。您已经像问题代码中的所有内容一样进行了更改。请创建一个minimal reproducible example。
-
那么当您在调试器下运行它时(提示提示),哪条指令触发了异常,寄存器值是多少?这应该可以帮助您弄清楚发生了什么。
-
一个提示:再次阅读单操作数
div指令的作用。 -
异常命名存在问题:在 Linux for x86 CPU 中,“浮点异常”通常确实描述了浮点问题,但它描述了整数除以零的情况。整数除法!
标签: c linux assembly printf nasm