32位汇编代码(GNU Linux)的64位转换最终处于无限循环中

时间:2017-03-03 13:43:58

标签: linux assembly 64-bit gnu gas

我正在关注使用32位GNU汇编程序的书Programming from the Ground Up作为其程序。我的机器是64位。通过逐字输入,我得到了前两个例子。没有任何错误。但是,第三个例子没有编译。我做了一些更改(例如,将l后缀更改为q以进行操作并使用r前缀而不是e前缀)到第三个示例,以便它现在编译得很好。现在的问题是它最终会陷入无限循环。

以下是代码:

power.s

# PURPOSE:
# Program to illustrate how functions work.
# This program will compute the value of
# 2^3 + 5^2 (= 8 + 25 = 33)

# Everything in the main program is stored in
# registers, so the data section doesn't have
# anything.

    .section .data

    .section .text
    .globl _start

_start:
    pushq   $3          # Push the second argument (the power)
    pushq   $2          # Push the first argument (the base)
    call    power       # Call the function power
    addq    $8, %rsp    # Move the stack pointer back

    pushq   %rax        # Save the first answer before calling again

    pushq   $2
    pushq   $5
    call    power
    addq    $8, %rsp    # Move the stack pointer back

    # The first answer is already in %rax, pop the second answer to %rbx
    popq    %rbx

    # Add the answers together and store the result in %rbx
    addq    %rax, %rbx

    movq    $1, %rax
    int     $0x80

    # FUNCTION: power
    # PURPOSE:  To exponentiate a number to a given power
    #
    # INPUT:
    # 1. The base number.
    # 2. The power to raise it to.
    #
    # OUPTUT:   Will give the result as a return value.
    #
    # NOTES:    The power must be positiive.
    #
    # VARIABLES:
    # 1. %rbx       - holds the base number
    # 2. %rcx       - holds the power
    # 3. -4(%rbp)   - holds the current result
    # 4. %rax       - used for temporary storage
    .type power, @function
power:
    pushq   %rbp            # Save old base pointer
    movq    %rsp, %rbp      # Make the stack pointer the base pointer
    subq    $4, %rsp        # Get room for our local storage

    movq    8(%rbp), %rbx   # The first argument in %rbx
    movq    12(%rbp), %rcx  # The first argument in %rcx

    movq    %rbx, -4(%rbp)  # The current result

power_loop_start:
    cmpq    $1, %rcx
    je      end_power
    movq    -4(%rbp), %rax  # Fetch the last rersult into %rax
    imulq   %rbx, %rax      # Multiply the base with the result and store in %rax
    movq    %rax, -4(%rbp)  # Update the result

    decq    %rcx            # Decrement the power
    jmp     power_loop_start

end_power:
    movq    -4(%rbp), %rax  # Store return value in %rax
    movq    %rbp, %rsp      # Restore the Stack pointer
    popq    %rbp            # Restore the Base pointer
    ret

知道哪里出错了?

以前的例子很好用:

exit.s

# PURPOSE:  Simple program that exits and returns a status code
#           back to the Linux kernel.
#
# INPUT:    None
#
# OUTPUT:   Returns a status code that can be viewed by typing:
#               echo $?
#           in the terminal after running the program.
#
# VARIABLES:
#           %eax holds the system call number
#           %ebx holds the return status
.section .data

.section .text
.globl _start

_start:

# This is the Linux kernel command number
# (system call) for exiting a program.
movl $1, %eax

# This is the sattus number we will return
# to the Operating System.
movl $0, %ebx

# This wakes up the kernel to run the exit command
int $0x80

maximum.s

# PURPOSE:      This program finds the maximum of a set of
#               data items.
#
# VARIABLES:    The registers have the following uses.
#
# %edi - Holds the index of the data item being examined.
# %ebx - Largest data item found.
# %eax - The current data item.
#
# The following memory locations are used:
#
# data_items - Contains the data. A '0' terminates the data.
#

    .section .data

# The data items go here
data_items:
    .long 3,67,34,222,45,75,54,34,44,33,22,11,66,0

    .section .text

    .globl _start

_start:
    movl    $0, %edi                                # Initialize the index register
    movl    data_items(, %edi, 4), %eax             # Load the first (0th) bye of
                                                    # data into %eax
    movl    %eax, %ebx                              # The first is the max so far

start_loop:
    cmpl    $0, %eax                                # See if the current item is 0
    je      loop_exit

    incl    %edi                                    # Increment the idex by 1
    movl    data_items(, %edi, 4), %eax             # Load the next item
    cmpl    %ebx, %eax                              # Compare the values
    jle     start_loop

    movl    %eax, %ebx                              # The new item is bigger, so
                                                    # move it to %ebx
    jmp     start_loop

loop_exit:
    # %ebx is the status code and it has the maximum element
    # We'll just return this as the maximum number
    movl    $1, %eax
    int     $0x80

0 个答案:

没有答案