0

I have a problem with execution of the project compiled in eclipse Version: 2021-12 (4.22.0)

The program is just 2 files:

  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 $4, %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
}

The program is compiled without any problems

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

but when I execute I get the following error:

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

And the stack dump looks as follows:

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

The same program is compiled and executed without any problems under Linux but the assemblies are written in INTEL syntax like that:

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

Under the Linux the 32-bit code is compiled using:

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

Could anybody please help me to identify where I go wrong?

Thanks Marek

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
IceDefcon
  • 35
  • 9
  • 5
    Use a debugger to step through your function to see what is going on and exactly which line it crashes on. One thing I find rather suspicious is that you're writing 32-bit code but calling it from a 64-bit program. – Raymond Chen Jan 04 '22 at 19:37
  • 3
    Eclipse is just a platform for running the tools that build and debug the program and then provides a terminal so you can see the results of running or debugging the program. While occasionally you'll run into a problem with Eclipse, this sort of problem is almost certainly going to be in the code or in the configuration of the tools. – user4581301 Jan 04 '22 at 19:39
  • The same program is compiled and executed without any problems under Linux but the assemblies are INTEL syntax. Under Linux the 32-bit code is compiled using: "nasm -f elf32 function.asm" and "g++ -m32 main.cpp function.asm" – IceDefcon Jan 04 '22 at 20:00
  • 2
    Combining Raymond Chen's comment above with the need for `-m32` in the Linux C++ build command suggests a possible course of action that you should explore. – user4581301 Jan 04 '22 at 20:01

2 Answers2

0

I've changed the Tool Settings to:

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

But I had to also had to modify the assemblies to be 64-bit + use INTEL syntax since I've change the GCC Assembler command to "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

With the above Tool Settings command and 64-bit INTEL syntax: The program compile without problems

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

But I still have an ERROR when executing:

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

And the Stack Trace:

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

Maybe there is a problem with Linker command (g++ m64 ???)

IceDefcon
  • 35
  • 9
0

OK, I've managed to figure this out

I've finally successfully executed the program by compiling at my cygwin64 that is linked to my ECLIPSE

And I've used two simple commands:

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

And the AT&T assembly syntax for the external function:

.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 $4, %esi
        loop lp

        popl %esi
        popl %ecx
        popl %ebp
        ret

For some reason the compiler requires me to add a carriage return to the end of the assembler file (function.asm)

So now, to launch my 32-bit source: I just probably need to hook up the above commands with my ECLIPSE

IceDefcon
  • 35
  • 9
  • 1
    Don't use `.code32` to assemble 32-bit machine code into a 64-bit executable. That's never what you want, unless you're writing a kernel that switches between modes. See [Assembling 32-bit binaries on a 64-bit system (GNU toolchain)](https://stackoverflow.com/q/36861903). Your `as` and `g++` are presumably still defaulting to `--64` / `-m64` respectively, so when decoded in 64-bit mode, this program will truncate the stack pointer to 32 bits when copying it to EBP. `movl 12(%ebp), %ecx` will decode as `movl 12(%rbp), %ecx`, but I don't think that helps you. – Peter Cordes Jan 05 '22 at 11:38
  • @PeterCordes Yes you right I should not use the 32bit code, I think this is a Cygwin related issue as I don't have any problems with compilation and execution of the same code but 64bit version on my Linux – IceDefcon Jan 11 '22 at 13:20