Jas*_*son 1 c assembly inline-assembly
我想使用C语言中的扩展asm来处理syscall(写)。一切都很好,我正在使用
#define write(RESULT, FD, BUFF, SIZE) \
asm volatile ("syscall" : \
"=a" (RESULT) : \
"D" (FD), "S" (BUFF), "d" (SIZE), "a" (1))
Run Code Online (Sandbox Code Playgroud)
这没有任何问题...例如
#define write(RESULT, FD, BUFF, SIZE) \
asm volatile ("syscall" : \
"=a" (RESULT) : \
"D" (FD), "S" (BUFF), "d" (SIZE), "a" (1))
int
main() {
int res;
write(res, 1, "Hello\n", 6);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我对此代码没有问题,但是我的问题是当我拨打此电话时
write(res, 1, "Hello\n", 6);
Run Code Online (Sandbox Code Playgroud)
循环使用100次
#define write(RESULT, FD, BUFF, SIZE) \
asm volatile ("syscall" : \
"=a" (RESULT) : \
"D" (FD), "S" (BUFF), "d" (SIZE), "a" (1))
int
main() {
int res;
for (int i = 0; i < 100; i++) {
write(res, 1, "Hello\n", 6);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是有一点...我对此代码也没有问题,但仅在调试模式下....如果我将程序设置为(发布)或优化模式,则此循环将永远执行!就像没有100倍的限制...仅在“发布”模式下发生,这会优化我的代码并使它出错!
是的...在“ debug”中找到了打击源代码,但在“ Release”模式中将其永久写入“ Hello”(无限制)
这是我使用 带有-O3选项的在线检查的汇编代码(GCC x86_64)
.LC0:
.string "Hello\n"
main:
movl $100, %ecx
movl $.LC0, %esi
movl $1, %edi
movl $6, %edx
.L2:
movl %edi, %eax
syscall
subl $1, %ecx
jne .L2
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
该syscall指令则会覆盖寄存器rcx和r11。编译器假定保留其值,从而导致无限循环。将这两个添加到问题列表以解决此问题:
#define write(RESULT, FD, BUFF, SIZE) \
asm volatile ("syscall" : \
"=a" (RESULT) : \
"D" (FD), "S" (BUFF), "d" (SIZE), "a" (1) : \
"rcx", "r11", "memory")
Run Code Online (Sandbox Code Playgroud)