Is there really no way to print an ascii string in assembly to standard output without using up all four general purpose registers?
+1
A:
Well.. If you linked against libc you can call puts
, then you'd have some callee-save registers... :-)
But yeah. The syscall interface is pass-by-register. Sorry.
Don't be so shocked. It'd be the same way if you were doing a function call on some calling conventions. For many platforms that's pretty standard. (Including all amd64 compilers I know of...)
asveikau
2009-10-29 02:51:10
+1
A:
You could write a function that takes the needed arguments from the stack.
Brian
2009-10-29 02:51:27
can you give me an example?
KJP
2009-10-29 02:57:08
+6
A:
Right, it takes three registers for the parameters plus one for the system call number...
But, x86 has pusha
and popa
, which will push and pop all the registers in one instruction.
$ cat hwa.S
write = 0x04
exit = 0xfc
.text
_start:
pusha
movl $1, %ebx
lea str, %ecx
movl $len, %edx
movl $write, %eax
int $0x80
popa
xorl %ebx, %ebx
movl $exit, %eax
int $0x80
.data
str: .ascii "Hello, world!\n"
len = . -str
.globl _start
$ as -o hwa.o hwa.S
$ ld hwa.o
$ ./a.out
Hello, world!
DigitalRoss
2009-10-29 03:22:37
What? That takes ten clock cycles for the pusha and popa. The eight independent pushes and pops take one each. If you're going to get down and dirty with assembly, you've got to keep the faith and run at max speed :-)
paxdiablo
2009-10-29 04:45:24
In any case, you could just create your own system call that used eax for the code and ebx for the address of a null-terminated string. Voila (although you'll need to convince Linus et al to get it into the mainstream kernel) - let me know how that goes :-)
paxdiablo
2009-10-29 04:49:32