x86-64 Linux NASM. Function parameter passing of type int array declared as a function in C++ file

Viewed 1647

I tried using this advice for this problem

For Linux programming arr[], n, &a, &b are passed in RDI, RSI, RDX and RCX.

and the output of the program doesn't sum up the integers in the array properly. It outputs a large number that is obviously wrong.

The two files found below were modified from the original 32-bit version found here. http://mcs.uwsuper.edu/sb/224/Intro/c_asm.html

What I want is to compile an assembly file that calls a function parameter in a C++ file called array.cpp and then link the resulting object file array.o with g++.

The problem I'm having has to do with either the passing of the proper registers onto the stack or maybe the number of bytes to add for each offset on the rsi register ( I used 8 since each stack element is 64 bits).

It could also be that the rbp register isn't properly loaded at the correct offsets of the array address and number of elements in the array.

 mov rcx, [rbp+24]   ; array length
 mov rsi, [rbp+16]    ; array address

Anyways, here's the array.cpp file and below it is the nasm file, I called it nasm_cpp.asm.

They compile, link and run with

nasm -f elf64 nasm_cpp.asm -o array.o
g++ -m64 array.cpp array.o
./a.out


#include <iostream>
using namespace std;

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

int main()
{
  int a[] = { 10, 10};  // array declaration
  int array_length = 2;                     // length of the array

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

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

This is nasm_cpp.asm below

;nasm -f elf64 nasm_cpp.asm -o array.o
;g++ -m64 array.cpp array.o
;./a.out
global array               ; required for linker and NASM
section .text              ; start of the "CODE segment"

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

       mov rcx, [rbp+24]   ; array length
       mov rsi, [rbp+16]    ; array address

       xor rax, rax        ; clear the sum value       
lp:    add rax, [rsi]      ; fetch an array element
       add rsi, 8         ; move to another element
       loop lp             ; loop over all elements

       pop rsi             ; restore used registers
       pop rdi
       pop rcx     
       pop rbp
       ret                 ; return to caller
1 Answers
Related