Встроенная сборка на Linux, запись строки из стека в стандартный вывод - PullRequest
1 голос
/ 16 июля 2010

как я могу написать строку (например, "Hello") в стандартный вывод из стека? без, data-сегментов, то есть.

void main() {
    __asm__(
                "movl  $0x4, %eax   \n\t"
                "movl  $0x1, %ebx   \n\t"
            //   put "Hello" on the 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"
             );
}

спасибо заранее

Ответы [ 3 ]

3 голосов
/ 16 июля 2010

Ответ 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;
}

Ответ 2:

int main()
{
    char[6] string = "hello";  // Space for string allocated on stack
    fputs(string, stdout);
    return 0;
}

С gcc второй ответ, кажется, генерирует следующее:

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

, который явно использует только стек.

0 голосов
/ 16 июля 2010

как я могу записать строку (например, "Hello") в стандартный вывод из стека?без, сегменты данных, то есть.

Что-то вроде строк:

  1. Распределить буфер по стеку, скажем, 8 байтов.(Проверьте, как GCC alloca () делает это.)
  2. Создать строку в буфере.«Привет» - 48 48 6c 6c 6f 00 00 00 (выровнено, дополнено нулями).Для представления строки должно быть достаточно двух 32-битных констант - 0x6c6c6548 и 0x0000006f.
  3. Передать адрес буфера в системный вызов записи.
  4. Восстановить указатель стека, где он был раньше (при необходимости).

Не могу быть более точным, так как я не очень осведомлен о встроенном ассемблере GCC и ABI x86.

0 голосов
/ 16 июля 2010
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;
}

Я не понимаю часть стека.Почему бы не использовать `movl% 0, %% ecx '?

...