Assembly idiv溢出异常asm 在C++之前,我对汇编非常陌生。 我试图创建一个简单的应用程序,将2到给定输入的所有素数打印出来 当我跑步时,它会崩溃,这很正常。看看OllyDbg,罪魁祸首是: move eax, ebx idiv ecx ; !!! here
这很奇怪,因为ecx不是0,值是EAX=0000 0004,ecx=0000 0002,它告诉我这是一个整数溢出异常C000 0095 除法过程中如何可能出现溢出?两个操作数均为32位 拼凑代码和ollydbg的屏幕截图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
%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还将告诉您它发生的确切位置。