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
Другие вопросы по тегам