Ich habe eine externe Funktion und ein struct
in token.c
definiert:Wie C extern Funktion aufrufen und Return-Struktur erhalten?
#include "stdio.h"
typedef struct token {
int start;
int length;
} t;
extern t get_token(int, int);
t get_token(int s, int l) {
printf("[C] new token: start [%d] length [%d]\n\n", s, l);
t m_T = {};
m_T.start = s;
m_T.length = l;
return m_T;
}
... damit ich _get_token
aus meiner Versammlung anrufen und einen neuen Token erhalten. In make_token.asm habe ich folgendes:
SECTION .data ; initialized data
mtkn: db "call: token(%d, %d)", 10, 0
mlen db "length: %d", 10, 0
mstt: db "start: %d", 10, 0
mend: db 10, "*** END ***", 10, 0
SECTION .text ; code
extern _get_token
extern _printf
global _main
_main:
; stash base stack pointer
push ebp
mov ebp, esp
mov eax, 5
mov ebx, 10
push ebx ; length
push eax ; start
call _get_token ; get a token
mov [tkn], eax
add esp, 8
; test token properties
push DWORD [tkn]
push mstt
call _printf
push DWORD [tkn + 4]
push mlen
call _printf
add esp, 16
.end:
push DWORD mend
call _printf
; restore base stack pointer
mov esp, ebp
pop ebp
SECTION .bss ; uninitialized data
tkn: resd 1
Der Ausgang ist:
[C] neues Token: start [5] Länge [10]
Start: 5
Länge : 0
Was fehlt mir, um sowohl Start und Länge zu bekommen? Die Ausgabe überprüft, dass die externe Funktion in C aufgerufen wird und die Werte in die Funktion geschoben werden.
Wenn ich [diese Tabelle] (http://en.wikipedia.org/wiki/X86_calling_conventions#List_of_x86_calling_conventions) richtig gelesen als die zweite Hälfte Ihrer Antwort sollte in EDX sein - „POD Rückgabewert 33-64 Bits in Die Größe wird über die EAX: EDX-Register zurückgegeben. " – zch
1) Geben Sie keine DEF-Strukturdefinitionen ein. 2) Da diese Struktur in einer anderen Datei deklariert ist, sollte die Definition in einer Headerdatei sein, die beide Quellendateien #include. 3) Referenzieren einer externen Funktion erfolgt nicht über extern. eher in einer gemeinsamen Headerdatei, die sowohl in der Quelldatei, in der die Funktion deklariert ist, als auch in der lokalen Datei über #include enthalten ist. Die Headerdatei hätte den Prototyp, der Linker den Rest. 4) Die Suchreihenfolge für #include-Dateien hängt davon ab, ob '< ...>' oder '...' 'verwendet wird. System-Header sollten immer die '<' and '>' – user3629249
diese Zeile verwenden: 'Return m_T;' wird nicht korrekt funktionieren, denn wenn die Funktion beendet wird, ist alles auf dem Stapel "verloren", so dass das Zurückgeben eines Elements, das sich auf dem Stapel befindet, ein nicht definiertes Verhalten ist. Da jedoch die tatsächliche vollständige Struktur zurückgegeben wird, anstelle eines Zeigers, ruft der Compiler memcpy() auf, um die Struktur in einen "versteckten" Speicherbereich zu kopieren (der für nichts anderes verwendet werden kann), und ruft dann erneut memcpy() auf Kopieren aus dem versteckten Speicherbereich in die Variable des Anrufers. Viel besser, einen dritten Parameter zu übergeben, der ein Zeiger auf die Instanz der Aufrufer der Struktur ist, und verwenden Sie diesen Zeiger – user3629249