Hallo,ich beschäftige mich zurzeit ein wenig mit x86 Assembler und versuche 'einfache' Programme zu basteln. Wie der Titel schon sagt, beschäftigt mich zur Zeit das auslesen der Kommandozeilen Parameter. Als Beispiel wie das funktioniert habe ich mir ein kleines C(++) Programm geschrieben und geschaut wie der Assemblercode davon aussieht. Der C-Code sieht wie folgt aus:
Code:
#include "stdio.h"
int main(int arc, char ** arcv)
{
printf("%d", arc);
return 0;
}
Wie man sieht wird hier einfach auf die Konsole geschrieben wie viele Parameter auf der Kommandozeile übergeben wurden.
In Assembler sieht das ganze dann (gekürzt) so aus:
Code:
...
_text SEGMENT BYTE PUBLIC 'CODE' ; section number 1
_main LABEL NEAR
push ebp
mov eax, 16 ; Warum wird 16 nach eax geladen? Für __alloca oder ___main?
mov ebp, esp
sub esp, 8
and esp, 0FFFFFFF0H ; Laut Google Stackalignment und hier unwichtig, richtig?
call __alloca ; Laut Google reserviert dies Speicher auf dem Stack, ist das korrekt?
call ___main ; Was macht dies? Hab bei Google keine vernünftige Antwort gefunden.
mov dword ptr [esp], offset ?_001
mov eax, dword ptr [ebp+8H]
mov dword ptr [esp+4H], eax
call _printf
leave
xor eax, eax
ret
...
.rdata SEGMENT BYTE PUBLIC 'CONST' ; section number 4
?_001 label byte
db 25H, 64H, 00H, 00H, 00H, 00H, 00H, 00H ; 0000 _ %d......
db 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00H ; 0008 _ ........
...
Kann mir wer erklären, ob das was ich oben in den Kommentaren geschrieben habe so richtig ist und was es mit __alloc und ___main auf sich hat?
Mein Nachbau sieht wie folgt aus:
Code:
DATA SECTION
FORMAT DD "%d",0
CODE SECTION
START:
PUSH EBP ; Org. Basepointer für Rücksprung auf dem Stack sichern
MOV EBP, ESP ; Basepointer durch aktuellen Stackpointer ersetzen
SUB ESP, 8 ; 8Byte auf dem Stack reservieren
MOV [ESP], ADDR FORMAT ; Adresse von "%d" auf den Stack legen
MOV EAX, [EBP+8H] ; Sollte eigentlich den wert von 'argc' nach EAX schieben
MOV [ESP+4H], EAX ; 'argc' unter die Adresse von"%d" auf den Stack legen
CALL printf ; printf aufrufen
XCHG EBP, ESP ; Aufräumen Stackpointer auf Basepointer setzen
POP EBP ; Alten Basepointer für Rücksprung laden
XOR EAX, EAX ; EAX auf 0 setzen
RET ; Verlassen...
Jetzt die Frage alles Fragen:
Warum funktioniert das oben und es wird korrekterweise die Anzahl an Parametern ausgegeben, während in meinem Nachbau nur Schwachsinn (scheinbar zufällige Zahl) ausgegeben wird?
Falls noch weitere Infos notwendig sind, schreit bitte. Dann werde ich diese nach Möglichkeit liefern.
Gruß,
Magnes