You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86汇编实现二分搜索返回C++主程序时触发访问违例疑栈错误

Fixing Access Violation When Returning from Assembly Binary Search to C++ Main

Hey there! Let's tackle that access violation you're hitting when your assembly binary search returns to C++ main. Since you confirmed the algorithm logic works via line-by-line debugging, this is almost certainly a stack misalignment or calling convention mismatch issue—super common when mixing assembly and C++. Let's break down the key checks and fixes:

1. Match Calling Conventions Between Assembly and C++

First, make sure your assembly code uses the same calling convention as your C++ function declaration:

  • C++ default (for extern "C"): cdecl convention, where the caller cleans up the stack after the function returns.
  • Assembly setup: Add .model flat, c at the top of your .asm file to enforce C-style calling conventions.
  • C++ declaration: Explicitly use extern "C" to avoid name mangling and ensure matching conventions:
    extern "C" int BinarySearch(int arr[], int target, int low, int high);
    

If you accidentally used stdcall (where the callee cleans up the stack), you'd need to adjust both:

  • Assembly: End the function with ret 16 (since 4 int parameters × 4 bytes = 16 bytes to clean up)
  • C++: Declare with __stdcall:
    extern "C" int __stdcall BinarySearch(int arr[], int target, int low, int high);
    

2. Properly Set Up and Tear Down the Stack Frame

Stack frame corruption is the #1 culprit here. Your assembly function must correctly save and restore the base pointer (ebp) to maintain stack integrity:

TITLE AsmBinarySearch Procedure (AsmBinarySearch.asm)
.586
.model flat, c  ; Critical for matching C++ calling convention
.code

BinarySearch proc
    ; Save old base pointer and set up new stack frame
    push ebp
    mov ebp, esp

    ; Save non-volatile registers (ebx, esi, edi are preserved across calls per C conventions)
    push ebx
    push esi
    push edi

    ; --------------------------
    ; Your binary search logic here
    ; Access parameters using:
    ; arr = [ebp+8], target = [ebp+12], low = [ebp+16], high = [ebp+20]
    ; Example: mov eax, [ebp+12]  ; Load target into eax
    ; --------------------------

    ; Restore saved registers in reverse order
    pop edi
    pop esi
    pop ebx

    ; Tear down stack frame and return
    mov esp, ebp  ; Reset stack pointer to base pointer position
    pop ebp       ; Restore original base pointer
    ret           ; For cdecl: caller cleans up stack; no argument needed
BinarySearch endp
end

If you skip push ebp/mov ebp, esp or forget to restore ebp before returning, the stack pointer will be misaligned when returning to main(), triggering an access violation.

3. Clean Up Local Stack Allocations

If your function uses local variables (e.g., sub esp, 4 to allocate space for a temporary variable), make sure to reclaim that space before tearing down the stack frame:

; Example: Allocate 4 bytes for a local variable
sub esp, 4
mov [esp], eax  ; Store value in local var

; Before restoring ebp:
add esp, 4  ; Reclaim local stack space

Failing to do this leaves the stack pointer offset, which breaks the return address lookup.

4. Verify Return Value Handling

In x86, integer return values are passed via the eax register. Ensure your binary search logic correctly sets eax to the result (index found or -1) before returning, and doesn't accidentally overwrite eax after setting it.

Quick Debugging Tip

When debugging, watch the esp and ebp registers at the start and end of your assembly function:

  • After push ebp, esp should be ebp_old - 4
  • Before ret, esp should match the value right after entering the function (after the call instruction pushes the return address)

If these values don't line up, your stack handling is off somewhere.


内容的提问来源于stack exchange,提问作者melanie93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:50:09