Я пытался использовать этот совет для этой проблемы
Для программирования 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
Parameters to functions are passed in the registers rdi, rsi, rdx, rcx, r8, r9,
. Это то, что вы думаете, может решить это? А как насчетrcx
рег. Как мне подсчитать, а также сохранить в нем значения перед нажатием стека? - person pandoragami   schedule 10.08.2017rcx
push
иpop
, и это все равно не сработало. - person pandoragami   schedule 10.08.2017mov rcx, rsi ; array length
mov rsi, rdi ; array address
. Поскольку вы добавляете 32-битные целые числа, вам нужно изменитьadd rax, [rsi]
наadd eax, [rsi]
и добавить 4 к адресу вместо 8 - изменитьadd rsi, 8
наadd rsi, 4
. - person Michael Petch   schedule 10.08.2017push rbp mov rbp, rsp
в начале иpop rbp
также можно удалить. - person Michael Petch   schedule 10.08.2017