在x86_64 linux上的C程序中进行内联汇编 [英] Inline assembly in C program on x86_64 linux

查看:244
本文介绍了在x86_64 linux上的C程序中进行内联汇编的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在linux x86_64上构建了一个用C和内联汇编编写的简短程序.应该将一个字符串写入stdout.我在互联网上的一篇文章中找到了它:

I've built a short program written on C and inline assembly on my linux x86_64. It is supposed to write a string to stdout. I found it in an article on the internet:

int write_call( int fd, const char * str, int len ){
    long __res;
    __asm__ volatile ( "int $0x80":
        "=a" (__res):"0"(__NR_write),"b"((long)(fd)),"c"((long)(str)),"d"((long)(len)) );
    return (int) __res;
}

void do_write( void ){
    char * str = "Paragon output string.\n";
    int len = strlen( str ), n;
    printf( "string for write length = %d\n", len );
    n = write_call( 1, str, len );
    printf( "write return : %d\n", n );
}

int main( int argc, char * argv[] ){
    do_write();
    return EXIT_SUCCESS;
}

但是在我运行它时,它无法正常工作,从而产生输出

But as I run it, it works incorrectly, making output

写回信:-14"

"write return : -14"

如果我在32位linux上构建并运行它,它将达到预期的效果.

If I build and run it on 32-bit linux it does what is expected.

经过研究,我发现指令"int $ 0x80"是x86指令,如果在x86_64上调用,则会截断寄存器中的参数.

After some research I fount out that instruction "int $0x80" is a x86 instruction and truncates arguments in registers if called on x86_64.

但是我找不到x86_64体系结构的"int $ 0x80"的适当替代.我的组装经验为零.

But I couldn't find a proper substitution of "int $0x80" for x86_64 architecture. I have zero experience in assembly.

我应该用什么代替"int $ 0x80"来获得预期的结果?

What should I put instead of "int $0x80" to receive expected result?

推荐答案

对于amd64,您需要使用"syscall"-并使用不同的寄存器-而不是"int 0x80":

For amd64, you need to use "syscall" - and use different registers - instead of "int 0x80":

http://cs.lmu.edu/~ray/notes/linuxsyscalls/

http://blog.rchapman .org/post/36801038863/linux-system-call-table-for-x86-64

http://crypto.stanford.edu/~blynn/rop/

这是一个很好的例子:

如何通过内联汇编(x86/amd64 linux)中的sysenter调用系统调用?

#include <unistd.h>

int main(void)
{
    const char hello[] = "Hello World!\n";
    const size_t hello_size = sizeof(hello);
    ssize_t ret;
    asm volatile
    (
        "movl $1, %%eax\n\t"
        "movl $1, %%edi\n\t"
        "movq %1, %%rsi\n\t"
        "movl %2, %%edx\n\t"
        "syscall"
        : "=a"(ret)
        : "g"(hello), "g"(hello_size)
        : "%rdi", "%rsi", "%rdx", "%rcx", "%r11"
    );
    return 0;

这篇关于在x86_64 linux上的C程序中进行内联汇编的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆