NASM Druck out-Zeit - Code nichts ausgibt
Frage
Ich bin nur mit ASM (NASM) und benötige Hilfe mit dem folgenden Ausschnitt getting started. Ich erhalte keine Fehler / Warnungen, es funktioniert einfach nicht ausgegeben nichts. Was ich erwartet hatte war für sie die Zeit (13) zu bekommen, dann ist das Ausdrucken (4), dann Ausfahrt (1). Auch kennt jemand ein paar gute (vorzugsweise NASM spezifisch) ASM-Tutorials?
section .bss
time: resb 255
section .text
global _start
_start:
mov eax, 13
int 0x80
mov eax, time
mov edx, 255
mov ecx, time
mov ebx, 1
mov eax, 4
int 0x80
mov eax, 1
int 0x80
Lösung
Dies ist dein Beispiel C. übersetzt Sie den Zeiger auf Zeit zu kopieren, anstatt EAX in den Puffer eax. das wäre immer noch nicht funktioniert, weil Sie einen char-Array für Schreib- und keine rohes integer wollen, den Müll gedruckt wird.
#include <stdlib.h>
char b[255];
int
main()
{
/* You wanted to do this which doesn't work
* because write wont take int* but char arrays
* *(int*)b=time(NULL);
*/
/* Instead you did */
time(NULL);
b;
write(1, b, 255);
exit(1);
}
Andere Tipps
Das erste Problem ist, dass Sie den sys_time sys Aufruf verstehen müssen. Es ist ein handliches Diagramm unter http://syscalls.kernelgrok.com/ das sagt, was die verschiedenen sys Anrufe benötigt als Eingabe in den Registern.
sys_time ist Systemaufruf 13, so
mov eax,13
ist gut
Allerdings sys_time erfordert auch eine Speicheradresse in EBX übergeben werden, wo es die aktuelle Zeit schreibt.
Eine schnelle Möglichkeit wäre etwas Platz auf dem Stack zugeordnet wird (wir etwas auf dem Stapel schieben können, wird der sys_time Wert überschreibt, warum nicht den Wert von EAX auf daran halten).
push eax
Dann füttert die Stapelzeiger in ebx
mov ebx, esp
Nun ist der Systemaufruf
int 80h
Jetzt können wir die Zeit vom Stapel pop (in beispielsweise EAX)
pop eax
Jetzt eax enthält die aktuelle Unix-Zeit (das heißt Anzahl der Sekunden seit 01 1970 Januar)
Um die trickyness Druck Zahlen direkt auf die Unix-Konsole vermeide ich betrügen und bieten ein vollständiges Beispiel, das über gcc in nasm und Verbindungen mit der C-Bibliothek erstellt und verwendet printf
[SECTION .data]
PrintNum db "%d",10,0 ;this is a c string so is null terminated
[SECTION .text]
extern printf
global main
main:
push ebp
mov ebp,esp
push ebx
push esi
push edi ; stuff before this for glibc compatibility
mov eax, 13
push eax
mov ebx, esp
int 0x80
pop eax
push eax ; push eax onto stack then the format string, then call printf to write eax to console, unwind stack pointer
push PrintNum
call printf
add esp,8
pop edi ; stuff after this for glibc compatibility
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
Übersetzen mit
nasm -f elf sys_time.asm
gcc sys-time.o -o sys-time
Obwohl, wenn Sie auf 64-Bit-Linux könnten Sie tun müssen (und haben die entsprechenden multilib gcc und glibc). Sie können dieses Programm nicht als native 64-Bit-Programm kompiliert, da es Push- und Pop verwendet, und Sie können eine 32-Bit-Register auf einen 64-Bit-Stack nicht drücken.
nasm -f elf32 sys_time.asm
gcc -m32 sys-time.o -o sys-time
Dann sollten Sie
$ ./systime
1310190574
Ich habe das auf 32-Bit getestet und 64-Bit-Linux und verwaltet den obigen Code kompiliert zu erhalten. Lassen Sie mich wissen, wenn Sie irgendwelche Probleme haben.
Um Ihre Frage zu betrachten nasm Tutorials zu beantworten, habe ich vor kurzem von „Assembly Language Schritt für Schritt, Third Edition“ von Jeff Duntemanns lernen. Siehe http://www.duntemann.com/assembly.html für Details und Beispielkapitel.