Linux上的C内联汇编,将字符串从堆栈写入到stdout

发布于 2024-09-09 09:57:02 字数 498 浏览 4 评论 0原文

我如何将字符串(例如“Hello”)从堆栈写入标准输出?也就是说,没有数据段。

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"
             );
}

提前致谢

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 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"
             );
}

thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

哭了丶谁疼 2024-09-16 09:57:02

答案 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

显然仅使用堆栈。

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.

子栖 2024-09-16 09:57:02
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”?

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'?

长梦不多时 2024-09-16 09:57:02

如何将字符串(例如“Hello”)从堆栈写入标准输出?也就是说,没有数据段。

大致意思是:

  1. 在堆栈上分配缓冲区,比如 8 个字节。 (检查 GCC alloca() 是如何做到这一点的。
  2. )缓冲区中的字符串。 “Hello”按字节为 48 65 6c 6c 6f 00 00 00 (对齐,用零填充)。两个 32 位常量 - 0x6c6c6548 和 0x0000006f - 应该足以表示该字符串。
  3. 将缓冲区的地址传递给 write 系统调用。
  4. 将堆栈指针恢复到之前的位置(如果需要)。

不能更精确了,因为我不太了解 GCC 内联 asm 和 x86 ABI。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文