我认为在我在汇编中创建的函数内部使用 printf 时遇到了一些麻烦。我做的函数是:
printnstars:
movl $0, %edi
movl 4(%esp), %ebx
starloop:
cmpl %ebx, %edi
je exitloop
incl %edi
pushl $star
call printf
addl $4, %esp
jmp starloop
exitloop:
ret
该函数接受一个数字作为参数,我将其移至 %ebx,并使用以下命令打印“*”的数量:
star:
.asciz "*"
这个函数做了它应该做的,但是当我尝试做这样的事情时我遇到了问题:
pushl (%ecx)
call printnstars
pushl (%ecx)
call printnstars
其中 (%ecx) 是 2。如果我只调用一次,它会按预期运行并打印 2 颗星,但是当我再次调用它时它会打印无限颗星。很明显 %ecx 一定在 printf 内部被弄乱了,因为我没有在我创建的任何东西中使用那个寄存器。我该怎么做才能确保 (%ecx) 在多次调用 printnstars 后保持不变?
还需要注意的是,它在一个函数内部使用,该函数正在打印一个直方图,每行上都有星号,表示数字出现的次数。我有所有基于 %ecx 的频率值,所以这就是我使用 (%ecx) 的原因。
最佳答案
What do I do to make sure that (%ecx) will remain constant through multiple calls to printnstars?
您将寄存器值保存在堆栈上的局部变量中。
此外,请记住 printf()
接受可变数量的参数,因为它事先不知道参数的数量和类型,所以它不会删除 on-堆栈参数并将它们从堆栈中移除(通过调整 esp
)成为调用者的责任。
关于汇编保留寄存器值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15034628/