来自GCC内联汇编的系统调用

时间:2010-06-02 13:44:18

标签: c linux gcc inline-assembly system-calls

是否可以使用内联汇编块中的系统调用来编写单个字符?如果是这样,怎么样?它应该看起来像这样的东西:

__asm__ __volatile__
                    (
                     " movl $1,  %%edx \n\t"
                     " movl $80, %%ecx \n\t"
                     " movl $0,  %%ebx \n\t"
                     " movl $4,  %%eax \n\t"
                     " int $0x80       \n\t"
                     ::: "%eax", "%ebx", "%ecx", "%edx"
                    );

ascii中80美元是'P',但没有返回任何内容。

任何建议都非常感谢!

3 个答案:

答案 0 :(得分:5)

您可以使用特定于体系结构的约束直接将参数放在特定寄存器中,而无需内联汇编中的$(document).ready(function() { oTable = $('#users').DataTable({ "processing": true, "serverSide": true, responsive: true, columnDefs: [ { responsivePriority: 1, targets: 1 }, { responsivePriority: 2, targets: -2 }, { responsivePriority: 3, targets: -1 } ], "ajax": "http://admin/products", "columns": [ <?php echo $string; ?> {data: 'action', name: 'action', orderable: false, searchable: false}, {data: 'delete', name: 'delete', orderable: false, searchable: false} ], 指令。此外,然后您可以使用movl运算符来获取字符的地址:

&

(在这种情况下,需要#include <sys/syscall.h> void sys_putc(char c) { // write(int fd, const void *buf, size_t count); int ret; asm volatile("int $0x80" : "=a"(ret): "a"(SYS_write), "b"(1), "c"(&c), "d"(1)); } int main(void) { sys_putc('P'); sys_putc('\n'); } 来表示系统调用符号 EAX 。)

=a(ret)

您还可以返回系统调用返回的写入字节数,并使用$ cc -m32 sys_putc.c && ./a.out P 作为约束来再次指示 EAX

"0"

答案 1 :(得分:2)

IIRC,你的例子中有两件事是错误的。 首先,你用mov $ 0,%ebx写入stdin 其次,write将指针作为它的第二个参数,所以要编写单个字符,你需要将该字符存储在内存中的某个位置,你不能直接将值写入%ecx

例如:

.data
char: .byte 80
.text
mov $char, %ecx

我在Linux中只做了纯粹的asm,从不使用gcc内联,你不能将数据放到程序集的中间,所以我不确定如何使用内联汇编获得指针。

编辑:我想我记得怎么做了。你可以将'p'推入堆栈并使用%esp

pushw $80
movl %%esp, %%ecx
... int $0x80 ...
addl $2, %%esp

答案 2 :(得分:1)

这样的东西

char p = 'P';

int main()
{
__asm__ __volatile__
                    (
                     " movl $1,  %%edx \n\t"
                     " leal p , %%ecx \n\t"
                     " movl $0,  %%ebx \n\t"
                     " movl $4,  %%eax \n\t"
                     " int $0x80       \n\t"
                     ::: "%eax", "%ebx", "%ecx", "%edx"
                    );
}

添加:请注意我已使用lea将char的有效地址加载到ecx寄存器中;对于ebx的值,我尝试了0美元和1美元,它似乎无论如何都有效......

避免使用外部字符

int main()
{
__asm__ __volatile__
                    (
                     " movl $1,  %%edx \n\t"
                     " subl $4, %%esp \n\t"
                     " movl $80, (%%esp)\n\t"
                     " movl %%esp, %%ecx \n\t"
                     " movl $1,  %%ebx \n\t"
                     " movl $4,  %%eax \n\t"
                     " int $0x80       \n\t"
                     " addl $4, %%esp\n\t"
                     ::: "%eax", "%ebx", "%ecx", "%edx"
                    );
}

N.B。:因为英特尔处理器的字节顺序而有效! :d