异常:STATUS_ACCESS_VIOLATION at rip=0010040108D 执行程序时

Exception: STATUS_ACCESS_VIOLATION at rip=0010040108D when executing program

我在eclipse Version: 2021-12 (4.22.0)中编译的项目执行有问题

该程序只有 2 个文件:

  1. function.asm
.code32 

.global array

.section .text

array:  pushl %ebp
        movl  %esp, %ebp
        pushl %ecx
        pushl %esi

        movl 12(%ebp), %ecx
        movl 8(%ebp), %esi

        xorl %eax, %eax

lp:     addl (%esi), %eax
        addl , %esi
        loop lp

        popl %esi
        popl %ecx
        popl %ebp
        ret
  1. main.cpp
#include <iostream>
using namespace std;

extern "C" int array(int a[], int length);   // external ASM procedure

int main()
{
  int a[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 0};  // array declaration
  int array_length = 10;                     // length of the array

  int sum = array(a, array_length);          // call of the ASM procedure

  cout << "sum=" << sum << endl;             // displaying the sum
}

程序编译没有问题

make all 
Building file: ../src/function.asm
Invoking: GCC Assembler
as  -o "src/function.o" "../src/function.asm"
Finished building: ../src/function.asm
 
Building file: ../src/main.cpp
Invoking: Cygwin C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.cpp"
Finished building: ../src/main.cpp
 
Building target: first.exe
Invoking: Cygwin C++ Linker
g++  -o "first.exe"  ./src/function.o ./src/main.o   
Finished building target: first.exe

但是当我执行时出现以下错误:

0 [main] first 1941 cygwin_exception::open_stackdumpfile: Dumping stack trace to first.exe.stackdump

堆栈转储如下所示:

Exception: STATUS_ACCESS_VIOLATION at rip=0010040108D
rax=0000000000000000 rbx=00000000FFFFCC30 rcx=0000000000000001
rdx=000000000000000A rsi=0000000000401109 rdi=0000000000008000
r8 =000000060001803F r9 =0000000000000000 r10=00000000FFFFCA50
r11=0000000100401189 r12=0000000180248C20 r13=00000000FFFFCC77
r14=0000000000000000 r15=00000000FFFFCC77
rbp=00000000FFFFCB80 rsp=00000000FFFFCB70
program=C:\WORKSPACE.ICE\first\Debug\first.exe, pid 102, thread main
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame        Function    Args
000FFFFCB80  0010040108D (000FFFFCBE0, 00100401109, 000FFFFCC77, 00180333F78)
000FFFFCB80  0018027FB40 (00100401109, 000FFFFCC77, 00180333F78, 0018027FB40)
000FFFFCB80  000FFFFCBB0 (000FFFFCC77, 00180333F78, 0018027FB40, 000FFFFCC30)
000FFFFCB80  000FFFFCBE0 (00180333F78, 0018027FB40, 000FFFFCC30, 00300000001)
000FFFFCB80  00100401109 (00180333F78, 0018027FB40, 000FFFFCC30, 00300000001)
000FFFFCBE0  00100401109 (00000000020, 70700000006FF00, 0018004A7AA, 00000000000)
000FFFFCCD0  0018004A816 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000  00180048353 (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFFFF0  00180048404 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace

同样的程序在Linux下编译和执行没有任何问题,但是程序集是用INTEL语法编写的:

global array               ; required for linker and NASM

section .text              ; start of the "CODE segment"

array: push ebp           
       mov ebp, esp        ; set up the EBP
       push ecx            ; save used registers
       push esi

       mov ecx, [ebp+12]   ; array length
       mov esi, [ebp+8]    ; array address

       xor eax, eax        ; clear the sum value
       
lp:    add eax, [esi]      ; fetch an array element
       add esi, 4          ; move to another element
       loop lp             ; loop over all elements

       pop esi             ; restore used registers
       pop ecx
       pop ebp
       ret                 ; return to caller

在Linux下32位代码编译使用:

nasm -f elf32 function.asm
g++ -m32 main.cpp function.asm

谁能帮我找出哪里出错了?

谢谢 马立克

我已将工具设置更改为:

GCC Assembler:          nasm -f elf64
Cygwin C++ Compiler:    g++ -m64 
Cygwin C++ Linker:      g++ -m64 

但我还必须将程序集修改为 64 位 + 使用 INTEL 语法,因为我已将 GCC 汇编器命令更改为“nasm -f elf64”

global array               ; required for linker and NASM

section .text              ; start of the "CODE segment"

array: push rbp
       mov  rbp, rsp       ; set up the EBP
       push rcx            ; save used registers
       push rsi

       mov rcx, [rbp+12]   ; array length
       mov rsi, [rbp+8]    ; array address

       xor rax, rax        ; clear the sum value

lp:    add rax, [esi]      ; fetch an array element
       add rsi, 4          ; move to another element
       loop lp             ; loop over all elements

       pop rsi             ; restore used registers
       pop rcx
       pop rbp
       ret                 ; return to caller

使用上面的工具设置命令和64位INTEL语法:程序编译没有问题

make all 
Building file: ../src/function.asm
Invoking: GCC Assembler
nasm -f elf64  -o "src/function.o" "../src/function.asm"
Finished building: ../src/function.asm
 
Building file: ../src/main.cpp
Invoking: Cygwin C++ Compiler
g++ -m64 -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.cpp"
Finished building: ../src/main.cpp
 
Building target: first.exe
Invoking: Cygwin C++ Linker
g++ -m64  -o "first.exe"  ./src/function.o ./src/main.o   
Finished building target: first.exe

但是执行的时候还是报错:

0 [main] first 1609 cygwin_exception::open_stackdumpfile: Dumping stack trace to first.exe.stackdump

以及堆栈跟踪:

Exception: STATUS_ACCESS_VIOLATION at rip=0010040108D
rax=0000000000000000 rbx=00000000FFFFCC30 rcx=0000000000000001
rdx=000000000000000A rsi=0000000000401109 rdi=0000000000008000
r8 =000000060001803F r9 =0000000000000000 r10=00000000FFFFCA50
r11=000000010040115A r12=0000000180248C20 r13=00000000FFFFCC77
r14=0000000000000000 r15=00000000FFFFCC77
rbp=00000000FFFFCB80 rsp=00000000FFFFCB70
program=C:\WORKSPACE.ICE\first\Debug\first.exe, pid 163, thread main
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame        Function    Args
000FFFFCB80  0010040108D (000FFFFCBE0, 00100401109, 000FFFFCC77, 00180333F78)
000FFFFCB80  0018027FB40 (00100401109, 000FFFFCC77, 00180333F78, 0018027FB40)
000FFFFCB80  000FFFFCBB0 (000FFFFCC77, 00180333F78, 0018027FB40, 000FFFFCC30)
000FFFFCB80  000FFFFCBE0 (00180333F78, 0018027FB40, 000FFFFCC30, 00300000001)
000FFFFCB80  00100401109 (00180333F78, 0018027FB40, 000FFFFCC30, 00300000001)
000FFFFCBE0  00100401109 (00000000020, 70700000006FF00, 0018004A7AA, 00000000000)
000FFFFCCD0  0018004A816 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000  00180048353 (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFFFF0  00180048404 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace

可能链接器命令有问题 (g++ m64 ???)

好的,我已经弄明白了

我终于通过在链接到我的 ECLIPSE 的 cygwin64 上编译成功地执行了该程序

我使用了两个简单的命令:

as function.asm -o function.o
g++ main.cpp function.o

以及外部函数的 AT&T 汇编语法:

.code32 

.global array

.section .text

array:  pushl %ebp
        movl  %esp, %ebp
        pushl %ecx
        pushl %esi

        movl 12(%ebp), %ecx
        movl 8(%ebp), %esi

        xorl %eax, %eax

lp:     addl (%esi), %eax
        addl , %esi
        loop lp

        popl %esi
        popl %ecx
        popl %ebp
        ret

出于某种原因,编译器要求我在汇编文件末尾添加一个回车符 return (function.asm)

现在,要启动我的 32 位源代码:我可能只需要将上述命令与我的 ECLIPSE 连接起来