从汇编过程写入返回值时出现意外页面错误

Cri*_*aru 2 c++ x86 assembly masm visual-studio

我正在尝试混合汇编(x86)和C++。我用汇编语言编写了一个过程,然后从 C++ 中调用它。

但是,当将返回值写入局部变量时,我收到写入权限冲突错误。

#include <iostream>


// will return 1 if all ok and 0 if b is 0
extern "C" int integerMulDiv(int a, int b, int* prod, int* quo, int* rem);

int main() {
    int a = 13, b = 4;
    int p, q, r;

    int res = integerMulDiv(a, b, &p, &q, &r);
    std::cout << p << '\t' << q << '\t' << r << std::endl;
    std::cout << res << std::endl << std::endl;

    res = integerMulDiv(31, 0, &p, &q, &r);
    std::cout << p << '\t' << q << '\t' << r << std::endl;
    std::cout << res << std::endl << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

汇编过程通过指针返回一些值,并通过 RAX 返回一个 int。

; Returns : 0 Error (division by 0)
;         : 1 All ok

; *prod = a * b
; *quo  = a / b
; *rem  = a % b
integerMulDiv proc

    push ebp
    mov ebp, esp
    push ebx  ; save ebp and ebx

    xor eax, eax

    mov ecx, [ebp + 8]  ; get a
    mov edx, [ebp + 12] ; get b (the divisor)

    or edx, edx ; check divisor
    jz invalidDivizor

    imul edx, ecx
    mov ebx, [ebp + 16] ; get address of prod
    mov [ebx], edx      ; write prod

    mov eax, ecx
    cdq ; extend to edx
    idiv dword ptr[ebx + 12]

    mov ebx, [ebp + 20] ; get address of quo
    mov [ebp], eax      ; write quo
    mov ebx, [ebp + 24] ; get address of rem
    mov [ebp], edx      ; write rem

    mov eax, 1          ; set success
    jmp returnFromProc

invalidDivizor:
    mov eax, 0          ; set failed

returnFromProc:
    pop ebx
    pop ebp
    ret   ; restore and return

integerMulDiv endp
Run Code Online (Sandbox Code Playgroud)

当第一次调用integerMulDiv尝试将结果写入res变量时,我收到错误。

反汇编看起来像这样:

    int res = integerMulDiv(a, b, &p, &q, &r);
002D24BD  lea         eax,[r]  
002D24C0  push        eax  
002D24C1  lea         ecx,[q]  
002D24C4  push        ecx  
002D24C5  lea         edx,[p]  
002D24C8  push        edx  
002D24C9  mov         eax,dword ptr [b]  
002D24CC  push        eax  
002D24CD  mov         ecx,dword ptr [a]  
002D24D0  push        ecx  
002D24D1  call        _integerMulDiv (02D133Eh)  
002D24D6  add         esp,14h  
002D24D9  mov         dword ptr [res],eax   <- The #PF happens here
Run Code Online (Sandbox Code Playgroud)

有谁知道发生了什么以及为什么?

Mik*_*l F 6

以下代码部分对我来说很突出。

idiv dword ptr[ebx + 12]

mov ebx, [ebp + 20] ; get address of quo
mov [ebp], eax      ; write quo
mov ebx, [ebp + 24] ; get address of rem
mov [ebp], edx      ; write rem
Run Code Online (Sandbox Code Playgroud)

我不确定您是否想要除以乘积地址后 12 个字节的内存内容。也许你的意思是[ebp + 12]

之后,您将地址加载到ebx,然后将值写入ebp