IDIV溢出异常ASM [英] idiv overflow exception asm
问题描述
我是很新的装配,仅前C C ++结果
我试图创建一个简单的应用程序,打印所有质数2至给定的输入结果
当我运行,它崩溃,这是正常的。综观OllyDbg的,有罪的一块是这样的:
I'm very new to assembly, before only C C++
I was trying to create a simple application that print all the prime number from 2 to given input
When I run, it crashes, and that's normal. Looking at OllyDbg, the guilty piece is this:
move eax, ebx
idiv ecx ; !!! here
这很奇怪,因为ECX不为0结果值是EAX = 0000 0004,ECX = 0000 0002,和它说我这是一个Integer_Overflow(例外C000 0095)结果
怎么可能有一个溢分裂过程中?两个操作数都是32位的结果
结果Floowing的code和OllyDbg的截图
It is strange because ecx is not 0
Values are EAX = 0000 0004, ECX = 0000 0002, and it says me that's an Integer_Overflow (exception C000 0095)
How it's possible to have an overflow during a division? Both operands are 32bit
Floowing the code and a screenshot of ollydbg
%include "asm_io.inc"
segment .data
input_msg db "Insert a number: ", 0
output_msg db "This is prime: ", 0
segment .bss
input resd 1
segment .text
global _asm_main
; input => input number
; ebx => current number to execute [2 .. input]
; ecx => counter from 2 to current [2 .. current]
_asm_main:
mov eax, input_msg
call print_string
call read_int
inc eax
mov [input], eax
call print_nl
mov ebx, 2h
_start_main_loop:
mov eax, [input] ; if current > input
cmp eax, ebx
jz _end_main_loop
mov ecx, 2h
_iteration:
cmp ebx, ecx
je _print_number
mov eax, ebx
idiv ecx ; unsigned division?
cmp edx, 0 ; if rem != 0 jmp
jne _end_iteration
inc ecx ; else inc ecx and re-divide
jmp _iteration
_print_number:
mov eax, output_msg
call print_string
mov eax, ebx
call print_int
call print_nl
_end_iteration:
inc ebx
jmp _start_main_loop
_end_main_loop:
popa
mov eax, 0
leave
ret
推荐答案
在整数溢出异常 IDIV
当n位除法的结果可能不适合正发生指令位寄存器。这是可能的,因为 IDIV
和 DIV
将整个寄存器对 EDX:EAX
。你的 EDX
值为1,你把 EDX:EAX
2,这将导致成位右移。这种转变移动 1
在 EAX
的MSB,和你有一个积极的结果 0x80000000的
greather比为0x7FFFFFFF
,根据文档。
Integer overflow exception on idiv
instruction occurs when result of n-bit division can not fit into n-bit register. That is possible because idiv
and div
divide the whole register pair EDX:EAX
. Your EDX
value is 1 and you divide EDX:EAX
by 2, which results into a bit shift to right. This shift moves 1
on EAX
´s MSB, and you have a positive result 0x80000000
greather than 0x7FFFFFFF
, what is illegal according to the documentation.
您可能会问自己:为什么会有这样的限制?它的存在,因为在负值(MSB集) EAX
不会是两个正整数的除法的一个有效的结果。
You may be asking yourself "why is there such restriction?". It's there, because a negative value (MSB set) in EAX
wouldn't be a valid result of division of two positive integers.
这个问题的一般解决方法是, EDX
的零内容之前无符号除法
A general solution for this problem is either to zero contents of EDX
before unsigned division
mov eax, ebx
xor edx, edx
div ecx ;unsigned division
...或符号扩展EAX(如果你期望负输入端,你不应该怎么一回事,因为没有负整数,可以是一个素数)。
...or to sign-extend EAX (if you expect negative input, which you shouldn't beacuse no negative integer can be a prime number).
mov eax, ebx
cdq
idiv ecx ;signed division
这篇关于IDIV溢出异常ASM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!