Mein Problem liegt derzeit noch an einer anderen Stelle: Ich schaffe es nicht Pointer zu übergeben um ein Array abzuarbeiten.
Folgendes Beispiel läuft bislang nicht bei mir:
Ja, der Fehler liegt aber nicht bei dir, sondern bei godbolt bzw. den calling conventions des gcc.....das war mir schon bei den ersten Beispielen mit Funktionen mit Parametern aufgefallen.
Exkurs in Calling conventions: https://en.wikipedia.org/wiki/X86_calli…ing_conventions
Kurz zusammengefasst bestimmen die calling conventions, wie die Funktionsparameter an den ASM-Code übergeben werden.
Wenn man sich den Anfang des ASM-Code anschaut
dann sieht man, dass die ersten beiden Parameter der Funktion die Register rdi (64 bit, die Adresse der Struct der zu addierenden doubles) und esi (32Bit, 5 Doubles sollen addiert werden) sind
esi ist der niedrige Teil des rsi - Registers
Die ersten beiden Parameter werden also in den Registern RDI und RSI übergeben....schaut man sich die calling conventions an, dann ist das
System V AMD64 ABI
The calling convention of the System V AMD64 ABI is followed on Solaris, Linux, FreeBSD, macOS,[26] and is the de facto standard among Unix and Unix-like operating systems. The OpenVMS Calling Standard on x86-64 is based on the System V ABI with some extensions needed for backwards compatibility.[27] The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, R9 (R10 is used as a static chain pointer in case of nested functions[28]: 21 ), while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for the first floating point arguments.
Unix-gedöns....gcc....wtf....![]()
Schau mal, ob du bei godbolt einen Compiler für Windows findest oder die calling conventions umstellen kannst...
Ich habe im von godbolt erstellten ASM-Code das register esi durch edx ersetzt und damit die Microsoft x64 calling convention erfüllt, der gcc kann das auch!!
Damit läuft dein Code:
#include <assembleit2_64.au3>
#include <array.au3>
#AutoIt3Wrapper_UseX64=y
#cs blablub
use64
push rbp
mov rbp,rsp
mov QWORD [rbp-0x18],rcx
mov DWORD [rbp-0x1c],edx ;Microsoft x64 calling convention
pxor xmm0,xmm0
movsd QWORD [rbp-0x8],xmm0
mov DWORD [rbp-0xc],0x0
jmp bla
blub:
mov eax,DWORD [rbp-0xc]
cdqe
lea rdx,[rax*8+0x0]
mov rax,QWORD [rbp-0x18]
add rax,rdx
movsd xmm0,QWORD [rax]
movsd xmm1,QWORD [rbp-0x8]
addsd xmm0,xmm1
movsd QWORD [rbp-0x8],xmm0
add DWORD [rbp-0xc],0x1
bla:
mov eax,DWORD [rbp-0xc]
cmp eax,DWORD [rbp-0x1c]
jl blub
movsd xmm0,QWORD [rbp-0x8]
pop rbp
ret
#ce blablub
; double data array
Global $tData = DllStructCreate("DOUBLE [5]")
For $i = 1 To 5
DllStructSetData($tData, 1, Number($i & "." & $i), $i)
Next
;assembliert den Code und gibt das Ergebnis aus
$ret = _AssembleIt2("double","blablub", "PTR", DllStructGetPtr($tData), "INT", 5)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
;Opcodes erzeugen
;~ $ret = _AssembleIt2("retbinary","blablub")
;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
;und ab damit in den DllCallAddress()
Local $aStructMem = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", DllStructGetSize(DllStructCreate("byte[86]")), "dword", 4096, "dword", 64)
Local $tCodeBuffer = DllStructCreate("byte[86]", Number($aStructMem[0])) ;Address aligned 64 and Memory is $MEM_COMMIT, $PAGE_EXECUTE_READWRITE
DllStructSetData($tCodeBuffer, 1,"0x554889E548894DE88955E4660FEFC0F20F1145F8C745F400000000EB2A8B45F44898488D14C500000000488B45E84801D0F20F1000F20F104DF8F20F58C1F20F1145F88345F4018B45F43B45E47CCEF20F1045F85DC3") ;write opcodes into memory
$ret=DllCallAddress("double:cdecl", DllStructGetPtr($tCodeBuffer), "PTR", DllStructGetPtr($tData), "INT", 5)
_arraydisplay($ret)
Alles anzeigen
Wenn die Calling conventions vom aufrufenden Programm und der Funktion übereinstimmen, dann fluppt es :o)
//EDIT
habs gefunden:
__attribute__((ms_abi))
Im c++-code des gcc erstellt code der Microsoft x64 calling convention
Global $sSourceCode = _
'__attribute__((ms_abi))' & @LF & _
'double sumArray(double *arr, int size) {' & @LF & _
' double sum = 0.0;' & @LF & _
' for (int i = 0; i < size; i++) {' & @LF & _
' sum += arr[i];' & @LF & _
' }' & @LF & _
' return sum;' & @LF & _
'}'
funzt!!!!