【问题标题】:How to call C function printf for an integer from assembly code如何从汇编代码中为整数调用 C 函数 printf
【发布时间】:2014-09-28 15:30:13
【问题描述】:

我无法从汇编代码中调用 printf。我的函数 end_power 旨在打印 power 的结果,但是每当我调用 printf 时,我都会遇到分段错误。 (我在 64 位的 linux 上运行程序)唯一不工作的部分是 end_power 函数,更具体地说是调用 printf 所涉及的行

# PURPOSE: This function is used to compute
#       the value of a number raised to
#       a power.
#
# INPUT:   First argument - the base number
#       Second argument - the power to
#       raise it to
#
# OUTPUT:  Will give the result as a return value
#
# NOTES:   The power must be 1 or greater
#
# VARIABLES:
#
#       %rbx - holds the base number
#       %rcx - holds the power
#
#       -8(%rbp) - holds the current result
#
#       %rax is used for temporary storage
#

.type power, @function
power:

    pushq   %rbp              # save old base pointer
    movq    %rsp, %rbp        # make stack pointer the base pointer
    subq    $8, %rsp          # get room for our local storage

    movq    16(%rbp), %rbx    # put first argument in %rax
    movq    24(%rbp), %rcx    # put second argument in %rcx

    movq    %rbx, -8(%rbp)    # store current result

power_loop_start:

    cmpq    $1, %rcx          # if the power is 1, we are done
    je      end_power

    movq    -8(%rbp), %rax    # move the current result into %rax
    imulq   %rbx, %rax        # multiply the current result by
                          # the base number
    movq    %rax, -8(%rbp)    # store the current result
    decq    %rcx              # decrease the power
    jmp     power_loop_start    # run for the next power

end_power:

    movq    -8(%rbp), %rdi    # return value goes in %rdi

    pushq -8(%rbp)
    pushq $fmtdec
    call printf
    add $16, %rsp

    movq    %rbp, %rsp        # restore the stack pointer
    popq    %rbp              # restore the base pointer
    ret

【问题讨论】:

  • 您是在尝试执行printf(i) 还是printf("%d", i)
  • 您是否尝试过在 C 中编写等价的代码,然后查看编译器汇编的内容? (即gcc -S
  • 调用约定完全不同。 en.wikipedia.org/wiki/…%rdi 中的第一个参数(格式字符串指针),%rsi 中的下一个参数!

标签: c linux assembly printf 64-bit


【解决方案1】:

64 位 Linux 的调用约定与 32 位 Linux 的调用约定大不相同。看一看:http://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI

改变

pushq -8(%rbp)
pushq $fmtdec
call printf
add $16, %rsp

mov $fmtdec,%rdi
mov -8(%rbp),%rsi
xor %eax, %eax
call printf

并认为这会覆盖您以前在 RDI 中的“返回值”。

【讨论】:

  • 感谢打印了两个数字相加但不是重新结果。我尝试在电源恢复后将其移至主功能,但尚未设法将其更改为在那里运行。但感谢您为我指明了正确的方向。
猜你喜欢
  • 2016-09-07
  • 2017-02-18
  • 2012-04-21
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
相关资源
最近更新 更多