3

我在我在汇编中创建的函数中使用 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) 的原因。

4

1 回答 1

2

我该怎么做才能确保 (%ecx) 通过多次调用 printnstars 保持不变?

您将寄存器值保存在堆栈上的局部变量中。

另外,请记住,printf()它采用可变数量的参数,并且由于它事先不知道它们有多少以及它们的类型,因此它不会删除堆栈上的参数并将它们从堆栈中删除(通过调整esp)变成调用者的责任。

于 2013-02-22T23:12:26.333 回答