在Dev-C++中定义GCC内联汇编中的字节(.在Windows上的AT&T语法中的ascii)

jyz*_*jyz 10 assembly gcc inline-assembly dev-c++ att

下面的代码只是在屏幕上显示一个消息框.
地址是硬编码的,以方便:

int main ()
{
    asm("xorl %eax, %eax        \n"
        "xorl %ebx, %ebx        \n"
        "xorl %ecx, %ecx        \n"
        "xorl %edx, %edx        \n"
        "pushl %ecx             \n" //$0x0
        "pushl $0x20206c6c      \n" //"  ll"
        "pushl $0x642e3233      \n" //"d.23"
        "pushl $0x72657375      \n" //"resu"
        "movl %esp, %ecx        \n" //store "user32.dll" address in %ecx
        "movl $0x7c801d7b, %ebx \n" //store address of LoadLibraryA in %ebx
        "pushl %ecx             \n"
        "call *%ebx             \n"
        "movl $0xef30675e, %ecx \n"
        "addl $0x11111111, %ecx \n"
        "pushl %ecx             \n"
        "pushl $0x42656761      \n"
        "pushl $0x7373654d      \n"
        "movl %esp, %ecx        \n"
        "pushl %ecx             \n"
        "pushl %eax             \n"
        "movl $0x7c80ae40, %ebx \n"
        "call *%ebx             \n"
        "movl %esp, %ecx        \n"
        "xorl %edx, %edx        \n"
        "pushl %edx             \n"
        "pushl %ecx             \n"
        "pushl %ecx             \n"
        "pushl %edx             \n"
        "call *%eax             \n"
        "xorl %eax, %eax        \n"
        "pushl %eax             \n"
        "movl $0x7c81cb12, %eax \n"
        "call *%eax             \n"
    );
}
Run Code Online (Sandbox Code Playgroud)

(我没有评论所有代码,因为我的问题不是关于代码)

我的问题是:有没有办法在程序集内联中编写字符串"user32.dll"而无需手动推送到堆栈?我的意思是在NASM中这样:db 'Hello'

我知道在AT&T语法中我能做到.ascii 'Hello'或者.string 'Hello'在gcc内联中怎么做?

请注意我在Windows XP SP3上使用Dev-C++

谢谢!

Mat*_*ery 9

是的,通过在内联汇编程序中使用汇编程序指令.诀窍是将字符串放在正确的位置(数据部分),您可以通过切换使用.section .data,然后再切换回来.section .text.

您必须为数据提供标签,以便您可以参考它; 我建议在这里使用本地标签语法(例如1:,标签是一个数字,并且您将其引用1b为第一个1:标签向后或1f第一个1:标签转发 - 请参阅GNU汇编程序文档以获取更多详细信息).

像这样:

int main(void)
{
  asm(".section .data      \n"
      "1: .asciz \"Hello\" \n"
      ".section .text      \n"
      "pushl $1b           \n"
      "call _puts          \n"
      "add $4, %esp        \n"
     );
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我没有一个Windows系统可以方便地测试它,但它编译好了,看起来应该在Linux上使用MinGW交叉编译器做正确的事情(我相信Dev-C++基于MinGW).

注意:这种技术通常适用于使用GNU工具链.如果你正在构建ELF二进制文件(例如本机Linux),那么有一种更简洁的方法可以切换回要使用的文本部分.previous,这意味着"无论前一部分.section是什么".(上面的例子,如果你改变在Linux上工作_puts,以puts考虑到不同的符号前缀约定.)