是否有可能使用内联汇编块内的系统调用编写单个字符? 如果是的话,怎么样? 它应该看起来像这样的东西:
__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" );
$ 80是ascii中的“P”,但是不会返回任何结果。
任何build议非常感谢!
就像是
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" ); }
注意:这是因为英特尔处理器的端到端的工作原理! :d
您可以使用体系结构特定的约束将参数直接放置在特定寄存器中,而无需movl
联汇编中使用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'); }
(在这种情况下,需要=a(ret)
来表示系统调用者EAX 。)
$ cc -m32 sys_putc.c && ./a.out P
您还可以返回系统调用返回的写入字节数,并使用"0"
作为约束来再次指示EAX :
int sys_putc(char c) { int ret; asm volatile("int $0x80" : "=a"(ret) : "0"(SYS_write), "b"(1), "c"(&c), "d"(1)); return ret; }
IIRC,在你的例子中有两件事是错误的。 首先,你正在给stdin写mov $ 0,%ebx其次,写指针的时候是第二个参数,所以要写一个字符就需要那个字符存储在内存中的某个地方,你不能直接把值写到% ECX
例如:
.data char: .byte 80 .text mov $char, %ecx
我只在Linux中完成纯粹的asm,从不使用gcc内联,不能将数据放入程序集的中间,所以我不知道如何使用内联汇编来获取指针。
编辑:我想我只记得如何做到这一点。 你可以将“p”推入堆栈并使用%esp
pushw $80 movl %%esp, %%ecx ... int $0x80 ... addl $2, %%esp