IDIV溢出异常ASM [英] idiv overflow exception asm

查看:386
本文介绍了IDIV溢出异常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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆