Reputation: 1363
I'm just getting started with ASM (NASM), and need some help with the following snippet. I get no errors/warnings, it just doesn't output anything. What I was expecting was for it to get the time (13), then print that out (4), then exit (1). Also, does anyone know of some good (preferably NASM specific) 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
Upvotes: 1
Views: 3165
Reputation: 365
The first problem here is that you need to understand the sys_time sys call. There is a handy chart at http://syscalls.kernelgrok.com/ that tells you what the various sys calls require as input in registers.
sys_time is system call 13, so
mov eax,13
is good
However sys_time also requires a memory address to be passed in ebx, where it writes the actual time.
A quick way would be to allocate some space on the stack (we can push anything on the stack, the sys_time value will overwrite it, why not stick the value of eax onto it).
push eax
Then feed the stack pointer into ebx
mov ebx, esp
Now make the system call
int 80h
Now we can pop the time off the stack (into e.g. eax)
pop eax
Now eax contains the current unix time (i.e. number of seconds since Jan 01 1970.)
To avoid the trickyness of printing numbers directly to the unix console I will cheat and provide a complete example that compiles in nasm and links with the c library via gcc and uses 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
Compile with
nasm -f elf sys_time.asm
gcc sys-time.o -o sys-time
Though if you are on 64-bit linux you might have to do (and have the relevant multilib gcc and glibc). You can't compile this program as a native 64-bit executable because it uses push and pop and you can't push a 32 bit register onto a 64 bit stack.
nasm -f elf32 sys_time.asm
gcc -m32 sys-time.o -o sys-time
Then you should get
$ ./systime
1310190574
I've tested this on 32 bit and 64 bit linux and managed to get the above code compiled. Let me know if you have any problems.
To answer your question regarded nasm tutorials, I have been learning recently from "Assembly Language Step By Step, Third Edition" by Jeff Duntemann. See http://www.duntemann.com/assembly.html for details and sample chapters.
Upvotes: 6
Reputation:
This is your example translated to C. You are copying the pointer to time to eax instead of eax to the buffer. Still that wouldn't work because you want a char array for write and not a raw integer which will print garbage.
#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);
}
Upvotes: 3