Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 保留汇编寄存器值?_Assembly_X86_Printf - Fatal编程技术网

Assembly 保留汇编寄存器值?

Assembly 保留汇编寄存器值?,assembly,x86,printf,Assembly,X86,Printf,我认为在汇编中创建的函数中使用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 该函数接受一个数字作为参数

我认为在汇编中创建的函数中使用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,并使用以下命令打印该数量的“*”s:

函数执行它应该执行的操作,但当我尝试执行以下操作时遇到问题:

    pushl (%ecx)
    call printnstars
    pushl (%ecx)
    call printnstars
其中(%ecx)是2。如果我只做一次调用,它的行为和预期的一样,并打印出两颗星,但当我再次调用它时,它打印出无限多颗星。很明显,%ecx一定是被printf内部搞乱了,因为我在创建的任何东西中都没有使用该寄存器。如何确保(%ecx)在多次调用printnstars时保持不变

另外,值得注意的是,这是在一个函数中使用的,该函数正在打印一个直方图,其中每行上都有星号,表示一个数字出现的时间。我所有的频率值都是基于%ecx,所以我使用(%ecx)

如何确保(%ecx)在多次调用printnstars时保持不变

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


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

好的,那么我应该在第一次呼叫之前添加PUSH%ecx,然后在第二次呼叫之前添加popl%ecx吗?另外,我确实在printf调用之后添加了$4,%esp,所以我没有正确地这样做吗…?您可以推两次,然后再调用两次函数。怎么样?处理堆栈参数上的printf。addl$4%esp不处理吗?啊,我错过了。可能是的。好吧,我推了两下,然后打了两次电话,这似乎奏效了:)谢谢。杰克,请不要诋毁你的问题。我不会删除这个,因为这是一个很好的问题,有一个很好的答案。
    pushl (%ecx)
    call printnstars
    pushl (%ecx)
    call printnstars