Assembly - Parameter uebergeben in C und Assembly

  • Themenstarter Themenstarter caffeine
  • Beginndatum Beginndatum
C

caffeine

Guest
Hallo zusammen,


Ich schlage mich derzeit mit Assembly rum um möchte hierbei nun folgendes erreichen und weiß nicht wie:

Angenommen ich habe eine Funktion die wie folgt aussieht:

Code:
int f1 (int a , int b){

....

}

Der Funktion f1 werden Parameter übergeben. Wie realisiere ich so etwas in Assembler ? Ich habe genau eine solche Funktion wie f1, die ich in Assembler umschreiben und anschliessen in meinen C Code wieder einbinden möchte.Wie funktioniert hierbei aber die Übergabe der Parameter a und b ? Initialisieren in Assembler ist kein Problem, ok ... Aber wie mach ich die Deklaration ?Habe da nichts passendes gefunden, bzw. nichts woraus ich hätte schlauer werden können ... Bin für jede Hilfe dankbar.

Tanye
 
Die Parameter für deine f1 Funktion musst du vorher auf den Stack schreiben und nach dem Aufruf der Funktion dann auch wieder vom Stack entfernen (per pop oder umbiegen des Stackpointers).

Also in etwa so:
Code:
push eax     ; zweiter Parameter fuer f1 
push ebx     ; erster Parameter  fuer f1 
call f1       
add esp,8    ; Parameter vom Stack entfernen
Um auf die Parameter innerhalb der Funktion f1 zuzugreifen, nimmst du dir einen Basepointer "ebp" zur Hilfe. Wenn du den direkt zu Anfang sicherst und mit dem Wert des Stackpointers beschreibst, kannst du die beiden Parameter mittels [ebp+8], für den ersten, bzw [ebp+12] für den zweiten Parameter anspringen.

Code:
f1:    push ebp       
       mov  ebp,esp
       ... 
       mov ebx,[ebp+8]     ; ersten Parameter in ebx laden       
       mov eax,[ebp+12]    ; zweiten Parameter in eax laden
       ...       
       pop ebp       
       ret

Hoffe das hilft dir ein wenig.
 
Zuletzt bearbeitet von einem Moderator:
Danke für die Antworten. Ich hab mir da einige Sachen zu angesehen, komme aber immer noch nicht ganz klar.

Code:
int f1( int n , int m , int k , int M1 , int M2 , int M){ ... }

Mein Ansatz:
Code:
.section .data 

# Leer, da keine konstanten

section .text

.global _start

_start:
          push M
          push M2
          push M1
          push k
          push m
          push n

          call f1

f1:
	#Stack Frame vorbereiten
	pushl	%ebp # Base-Pointer speichern
	movl	%esp,%ebp # Stack-Pointer in ebp speichern

Bei Programmbeginn zeigt ESP auf eine Stelle im Stack, die die Rückkehradresse zum Betriebssystem enthält, deshalb speichere ich sie also in dem EBP. Das versteh ich soweit.Aber wie geht's weiter ? Befindet sich deshalb jetzt meine Variable "n" an der Stelle EBP+8 und m an EBP+12 usw. ? @Lord_Nykon Du speicherst die Variablen in den Registern soweit ich das verstanden hab aber ich habe doch nur EAX bis EDX ... Das sieht mir nach zu wenig aus für obige Parameter bin etwas verwirrt.
 
Falls dir das ein wenig weiterhilft:

An der Stelle [ebp+4] steht die Rücksprungaddresse zum Offset nach dem
call f1 . Der Befehl call legt diese auf dem Stack ab und der Befehl ret springt dorthin zurück. d.h. damit wäre die "Lücke"
von [ebp] zu [ebp+8] <-- erster Parameter, in deinem Fall n , geschlossen.
Danach geht's, wie du richtig erkannt hast in Viererschritten (32bit) weiter.
[ebp+12] wäre der zweite Parameter, [ebp+16] der dritte,. usw..

mfg
ss5
 
Falls dir das ein wenig weiterhilft:

An der Stelle [ebp+4] steht die Rücksprungaddresse zum Offset nach dem
call f1 . Der Befehl call legt diese auf dem Stack ab und der Befehl ret springt dorthin zurück. d.h. damit wäre die "Lücke"
von [ebp] zu [ebp+8] <-- erster Parameter, in deinem Fall n , geschlossen.
Danach geht's, wie du richtig erkannt hast in Viererschritten (32bit) weiter.
[ebp+12] wäre der zweite Parameter, [ebp+16] der dritte,. usw..

mfg
ss5

Hey, Jop das hab ich verstanden und seh ich auch alles ein. Mein Problem ist genau dass was der Linker mir versucht zu verstehen zu geben :

PHP:
test.o:test.s:21: undefined reference to `M'
test.o:test.s:22: undefined reference to `M2'
test.o:test.s:23: undefined reference to `M1'
test.o:test.s:24: undefined reference to `k'
test.o:test.s:25: undefined reference to `m'
test.o:test.s:26: undefined reference to `n'

Woher weiss er was die Variablen für einen Hintergrund haben ?
Oder behebt sich das Problem zur Laufzeit selbst ? Sprich wenn es tatsächlich von dem C-Code aus dem heraus es aufgerufen werden soll, ... aufgerufen wird :D

Code:
_start:            # Argumente in umgekehrter Reihenfolge auf den Stack pushen
        push    M  # Pushe M auf Stack
        push    M2 # Pushe M2 auf Stack
        push    M1 # Pushe M1 auf Stack  
        push    k  # Pushe k auf Stack
        push    m  # Pushe m auf Stack
        push    n  # Pushe n auf Stack

        call mmul #Calle mmul Funktion

mmul:
        push    %ebp            #Stack Frame vorbereite
        movl    %esp,   %ebp    #(2)


        movl    8(%ebp), %eax

So wie ich das jetzt gemacht habe muss ich theoretisch das erste Argument was, da rückwärts gepusht wurde, n sein muss, in EAX liegen.
 
Ist es jetzt irgendwie Inlineassembly oder sind die Dateien getrennt? Dann weiß der Linker erstmal nichts von "M, M2" usw (ok, der dürfte das schon wissen, aber die Variablen müssten dann anders deklariert werden)
Ich glaube auch nicht, dass Dein Code das braucht - Variablennamen sind eher was für schwache Programmierer, die sich keine direkten Adressen merken können ;).

Bsp:
Code:
.text
.globl	_myadd
.def	_myadd
_myadd:
	push	%ebp
	movl	%esp, %ebp
	movl 8(%ebp), %eax
	add 12(%ebp), %eax
	leave
	ret
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

extern uint32_t myadd(uint32_t, uint32_t);

int main(void) {
  printf("%d", myadd(30,100));
  getchar();
  return 0;
}
Code:
bash-3.1$ gcc -m32 add.s main.c
bash-3.1$ ./a
130
bash-3.1$
 
Zurück
Oben