汇编保留寄存器值?

标签 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

该函数接受一个数字作为参数,我将其移至 %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/

相关文章:

assembly - 找到一个空闲的中断槽

assembly - stdcall asm 浮点参数

c - printf 原始数据到固定长度的十六进制输出

assembly - 如何将 ST(0) 移动到 EAX?

linux - 汇编代码一直显示段错误

assembly - 为什么 x86 nopl 指令需要一个操作数?

architecture - 用于培训嵌入式开发的 x86 模拟器

c - 当我告诉 printf 打印变量时会发生什么?

c - printf 修改字符串

assembly - EMU8086 是否有错误,或者我编写此代码时犯了错误?