我想用scanf来获取输入,我的想法是循环scanf直到它返回负数(错误)。由于某种原因scanf将第一个输入存储在指定的变量中并返回负数,它不应该正确地完成它?下面是我的代码的一部分
.global main
main:
movl $var, %edx
in:
push %edx
push $inp
call scanf
jl done
add $8, %esp
add $4, %edx
jmp in
done:
...
.data
inp: .asciz "%d"
var: .space 4*100
我用的是AT&T汇编
1条答案
按热度按时间dffbzjpn1#
函数在EAX中返回(对于整数/指针),而不是FLAGS。
**您需要
test %eax,%eax
**根据返回瓦尔设置FLAGS,然后才能对其进行分支。函数不会为您做这些。
在i386 System V的调用约定中(像所有标准的调用约定一样),FLAGS是call-crobbered的,所以对条件代码中保留什么函数没有要求。(该约定确实要求在call和ret时DF=0)。它并不长,也不容易阅读。
或者,您可以看看编译器是怎么做的,因为编译器创建的全局(非
static
)函数将遵守ABI是一个很好的假设。int foo(){return 1;}
编译为mov $1, %eax
;ret
,这会使FLAGS不受影响。(https://godbolt.org/z/3a1jjaeM1)在手工编写的asm中,使用自定义的调用约定是完全可以的,其中FLAGS保存返回值,或者是返回值之一。(Asm没有C中只有一个按值返回值对象的恼人限制。)参见 * Is it considered bad practice to use the flags register as a boolean return value? *(不,MacOS / FreeBSD对系统调用也是这样做的。)
还要注意,EDX是被调用的;为指针选择一个不同的寄存器,如EDI、ESI或EBX,这样scanf就不会破坏它。