如何从汇编代码中调用C函数printf作为整数

时间:2014-09-28 15:30:13

标签: c linux assembly printf 64-bit

我无法从汇编代码调用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

1 个答案:

答案 0 :(得分:0)

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。