Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly idiv溢出异常asm 在C++之前,我对汇编非常陌生。 我试图创建一个简单的应用程序,将2到给定输入的所有素数打印出来 当我跑步时,它会崩溃,这很正常。看看OllyDbg,罪魁祸首是: move eax, ebx idiv ecx ; !!! here_Assembly_X86_Nasm - Fatal编程技术网

Assembly idiv溢出异常asm 在C++之前,我对汇编非常陌生。 我试图创建一个简单的应用程序,将2到给定输入的所有素数打印出来 当我跑步时,它会崩溃,这很正常。看看OllyDbg,罪魁祸首是: move eax, ebx idiv ecx ; !!! here

Assembly idiv溢出异常asm 在C++之前,我对汇编非常陌生。 我试图创建一个简单的应用程序,将2到给定输入的所有素数打印出来 当我跑步时,它会崩溃,这很正常。看看OllyDbg,罪魁祸首是: move eax, ebx idiv ecx ; !!! here,assembly,x86,nasm,Assembly,X86,Nasm,这很奇怪,因为ecx不是0,值是EAX=0000 0004,ecx=0000 0002,它告诉我这是一个整数溢出异常C000 0095 除法过程中如何可能出现溢出?两个操作数均为32位 拼凑代码和ollydbg的屏幕截图 %include "asm_io.inc" segment .data input_msg db "Insert a number: ", 0 output_msg db "This is prime: ", 0 segment .bss input

这很奇怪,因为ecx不是0,值是EAX=0000 0004,ecx=0000 0002,它告诉我这是一个整数溢出异常C000 0095 除法过程中如何可能出现溢出?两个操作数均为32位 拼凑代码和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

当n位除法的结果无法放入n位寄存器时,idiv指令上会出现整数溢出异常。这是可能的,因为idiv和div分割整个寄存器对EDX:EAX。您的EDX值为1,将EDX:EAX除以2,这将导致向右移位。此移位在EAX的MSB上移动1,得到的正结果0x8000000大于0x7FFFFFFF,根据

你可能会问自己,为什么会有这样的限制?。这是因为EAX中设置的负值MSB不是两个正整数除的有效结果

此问题的一般解决方案是在无符号除法之前将EDX的内容置零

mov eax, ebx
xor edx, edx
div ecx ;unsigned division
…或者,如果您期望负输入,则对extend EAX进行签名,这是不应该的,因为任何负整数都不能是素数

mov eax, ebx
cdq 
idiv ecx ;signed division

您完全忽略了idiv将edx:eax除以ecx。您需要添加CDQ以将extend eax签名到edx中。如果使用unsigned div,也会发生相同的错误。这更奇怪。但现在使用xor/cdq时,如果使用div,那么就不必考虑符号扩展,而是将操作数视为无符号数。只需使用xor edx将edx、edx归零,并且不使用干熄焦。有人能告诉我为什么人们投票-1这是一个合法的、已经回答过的问题吗?啊啊啊啊啊!我喜欢吃,谢谢。还有一个小问题:当我运行这个程序时,现在使用的是cdq,它说的是“阅读时违反访问权限”。它还会是“div”指令吗?这不应该是因为你在div中没有阅读,但在这个问题之前,我认为div没有生成过多的内容。然而,在你看来这是可能的?如果你在其他地方使用EDX来访问内存也是可能的。我不这么认为。但我用的是保尔·卡特博士的pcasm库。可能是问题吗?你有OllyDbg,试着找出答案。OllyDbg还将告诉您它发生的确切位置。