J'ai essayé d'utiliser ces conseils pour ce problèmex86-64 NASM Linux. paramètre Fonction passage d'un tableau de type int déclaré en fonction en C++ fichier
For Linux programming arr[], n, &a, &b are passed in RDI, RSI, RDX and RCX.
et la sortie du programme ne résume pas les entiers dans le tableau correctement . Il produit un grand nombre qui est évidemment faux.
Les deux fichiers trouvés ci-dessous ont été modifiés à partir de la version 32 bits d'origine trouvée ici. http://mcs.uwsuper.edu/sb/224/Intro/c_asm.html
Ce que je veux est de compiler un fichier d'assemblage qui appelle un paramètre de fonction dans un fichier C++ appelé array.cpp
puis lier le fichier objet résultant array.o
avec g++
. Le problème que je rencontre concerne le passage des registres appropriés sur la pile ou peut-être le nombre d'octets à ajouter pour chaque décalage sur le registre rsi
(j'ai utilisé 8 puisque chaque élément de pile est 64 bits).
Il se pourrait aussi que le registre rbp
est pas correctement chargé les décalages corrects de l'adresse du tableau et nombre d'éléments dans le tableau.
mov rcx, [rbp+24] ; array length
mov rsi, [rbp+16] ; array address
Quoi qu'il en soit, voici le fichier array.cpp
et au-dessous est le fichier nasm, je l'ai appelé nasm_cpp.asm
.
Ils compilent, lien et exécuter avec
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
}
C'est nasm_cpp.asm ci-dessous
;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
Les paramètres sont transmis dans des registres sur x86-64. Google pour "SYS V ABI x64" –
Ici, http://wiki.osdev.org/System_V_ABI indique "Les paramètres des fonctions sont passés dans les registres rdi, rsi, rdx, rcx, r8, r9,". Est-ce que ce que vous pensez pourrait le résoudre? Qu'en est-il du reg 'rcx' Comment devrais-je compter et sauvegarder les valeurs avant que la pile ne soit poussée? – pandoragami
J'ai enlevé 'rcx'' push' et 'pop' et cela ne fonctionnait toujours pas. – pandoragami