问题
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