C inline assembly on linux, write string from stack to stdout
how can i write a string (eg. "Hello") to stdout from the stack? without, data-segments, that is.
void main() {
__asm__(
"movl $0x4, %eax \n\t"
"movl $0x1, %ebx \n\t"
// put "Hello" on 开发者_如何学JAVAthe stack and load its address into %ecx
"movl $0x5, %edx \n\t"
"int $0x80 \n\t"
"movl $0x1, %eax \n\t"
"movl $0x0, %ebx \n\t"
"int $0x80 \n\t"
);
}
thanks in advance
Answer 1:
int main()
{
const char* string = "hello"; // string is not in a data segment, it's in the text segment
fputs(string, stdout);
return 0;
}
Answer 2:
int main()
{
char[6] string = "hello"; // Space for string allocated on stack
fputs(string, stdout);
return 0;
}
With gcc the second answer seems to generate the following:
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl $1819043176, -10(%ebp) ;<< hell
movw $111, -6(%ebp) ;<< o\0
movl stdout, %eax
movl %eax, 4(%esp)
leal -10(%ebp), %eax
movl %eax, (%esp)
call fputs
movl $0, %eax
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
which clearly only uses the stack.
int main() {
char *hello = "Hello world!\n";
__asm__("\
movl $4, %%eax\n\
movl $0, %%ebx\n\
push %0\n\
pop %%ecx\n\
movl $13,%%edx\n\
int $0x80" : :"g"(hello));
return 0;
}
I don't understand the stack part. Why dont't use `movl %0,%%ecx'?
how can i write a string (eg. "Hello") to stdout from the stack? without, data-segments, that is.
Something along the lines:
- Allocate buffer on stack, say 8 bytes. (Check how GCC alloca() does that.)
- Create the string in the buffer. "Hello" bytewise is 48 65 6c 6c 6f 00 00 00 (aligned, padded with zeros). The two 32bit constants - 0x6c6c6548 and 0x0000006f - should suffice to represent the string.
- Pass the address of the buffer to the write syscall.
- Restore the stack pointer where it was before (if needed).
Can't be more precise as I'm not very up-to-date on the GCC inline asm and x86 ABI.
精彩评论