开发者

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:

  1. Allocate buffer on stack, say 8 bytes. (Check how GCC alloca() does that.)
  2. 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.
  3. Pass the address of the buffer to the write syscall.
  4. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜