gcc内联asm x86 / linux:64bit需要静态,但不是32bit。为什么呢?

时间:2017-12-25 08:05:46

标签: linux gcc assembly x86-64 inline-assembly

下面的hello world程序(纯粹的独立linux / x86代码)编译得很好,但是当字符串"hello, world\n"是本地堆栈变量时会出现问题:在64位中,没有输出,除非本地字符串声明之前是关键字static;但在32位,不需要关键字!为什么呢?

  

编辑:

     

这似乎是32位和64位内联之间的不一致   ASM!

     

正如在另一个链接中指出的那样,问题是64位系统调用不同于32位,并且必须被调用的方式与在   以下代码int 0x80(仅适用于32位)。

(当然,如果字符串在数据存储器中成为全局/外部,则没有问题。)

使用gcc 5.4.0和4.8.4验证。请参阅代码注释中的编译命令行。

/*
Standalone linux/x86 hello world program.  Compile in 32bit or 64bit with:

    gcc -m32|-m64 -Wall -nostdlib -e main prog.c

Or separate compile/assemble/link:

    32bit:
    gcc -m32 -Wall -nostdlib -S -o prog.s prog.c
    as -32 -o prog.o prog.s
    ld -melf_i386 -e main -nostdlib -o a.out prog.o

    64bit:
    gcc -m64 -Wall -nostdlib -S -o prog.s prog.c
    as -64 -o prog.o prog.s
    ld -melf_x86_64 -e main -nostdlib -o a.out prog.o
*/
void main(void) {
    unsigned long snum, fd, len, exitcode;

    /* In 64bit, the program gives no output unless the local declaration
       below has the keyword static, but in 32bit it works fine without it.
       Why??  (If the string is made global (data section) then it works
       in both 32bit and 64bit.)  Verified with gcc 5.4.0 and gcc 4.8.4.
    */
    char str[] = "hello, world\n";

    snum=4; fd=1; len=13;
    asm volatile (  /* Syscall write */
        "int $0x80\n\t" : : "a" (snum), "b" (fd), "c" (str), "d" (len));
    snum=1; exitcode=0;
    asm volatile (  /* Syscall exit*/
        "int $0x80\n\t" : : "a" (snum), "b" (exitcode));
}

0 个答案:

没有答案