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

我怕爱的太早我们不能终老 提交于 2019-12-12 14:23:40

问题


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:


I followed the suggestions in the comments posted below the question and it works now, the cpp file is the same as above.

;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  

       mov rcx, rsi   ; array length
       mov rsi, rdi    ; array address

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

       pop rbp

       ret                 ; return to caller


来源:https://stackoverflow.com/questions/45619224/x86-64-linux-nasm-function-parameter-passing-of-type-int-array-declared-as-a-fu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!