x86-64 Linux NASM. Передача параметров функции массива типа int, объявленного как функция в файле C++
Я попытался использовать этот совет для этой проблемы
Для программирования Linux arr[], n, &a, &b передаются в RDI, RSI, RDX и RCX.
и результат программы не суммирует целые числа в массиве должным образом. Он выводит большое число, что явно неверно.
Два файла, найденные ниже, были изменены по сравнению с оригинальной 32-битной версией, найденной здесь. http://mcs.uwsuper.edu/sb/224/Intro/c_asm.html
Я хочу скомпилировать файл сборки, который вызывает параметр функции в файле C++ с именем array.cpp
а затем связать полученный объектный файл array.o
с g++
,
Проблема, с которой я столкнулся, связана с передачей соответствующих регистров в стек или, возможно, с количеством байтов, добавляемых для каждого смещения на rsi
регистр (я использовал 8, так как каждый элемент стека составляет 64 бита).
Также может быть, что rbp
регистр неправильно загружен при правильных смещениях адреса массива и количества элементов в массиве.
mov rcx, [rbp+24] ; array length
mov rsi, [rbp+16] ; array address
В любом случае, вот array.cpp
файл и ниже это файл NASM, я назвал его nasm_cpp.asm
,
Они компилируются, связываются и работают с
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
}
Это nasm_cpp.asm ниже
;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 ответ
Я следовал советам в комментариях, размещенных ниже вопроса, и теперь он работает, файл cpp такой же, как и выше.
;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