装配 - 带子程序的Segfault

时间:2016-07-15 21:46:47

标签: assembly segmentation-fault x86-64 frequency

我试图调试为什么我的子程序中出现了段错误。

它发生在子程序末尾的ret行上 - 就像在句子末尾达到0x00字节一样。

主要:

                .data
string:         .string "aaaaaaaaaaa"
endofstring:    .space  8
msg:            .string "%c occurs %d times \n"

                .text
                .global main

main:

    mov     $string,%rsi            #rsi = string storage
    mov     $0x61, %ah              #storage of a 
    mov     $0x65, %al              #storage of e
    mov     $0x69, %bh              #storage of i
    mov     $0x6F, %bl              #storage of o
    mov     $0x75, %ch              #storage of u


#Case A
    mov     %ah,%cl                 #1 byte register for cmp later on.
    mov     $0, %rax                #initialize count to 0
    call    FREQ                    #Generate %rax value for 


    mov     %rax, %rdx              #count for printf (2nd argument)
    mov     $msg, %rdi              #format for printf(1st argument)
    mov     %r8, %rsi               #ch for printf (3rd argument)

    xor     %rax, %rax              #reset %rax for printf output

    call    printf                  #print the frequency value of the ch in string


#Case E
    mov     %al,%cl
    mov     $0, %rax                #initialize count to 0
    call    FREQ

    mov     %rax, %rdx              #count for printf (2nd argument)
    mov     $msg, %rdi              #format for printf(1st argument)
    mov     %r8, %rsi               #ch for printf (3rd argument)

    xor     %rax, %rax              #reset %rax for printf output

    call    printf                  #print the frequency value of the ch in string

#Case O
    mov     %bh,%cl
    mov     $0, %rax                #initialize count to 0
    call    FREQ

    mov     %rax, %rdx              #count for printf (2nd argument)
    mov     $msg, %rdi              #format for printf(1st argument)
    mov     %r8, %rsi               #ch for printf (3rd argument)

    xor     %rax, %rax              #reset %rax for printf output

    call    printf                  #print the frequency value of the ch in string

#Case I
    mov     %bl,%cl
    mov     $0, %rax                #initialize count to 0
    call    FREQ

    mov     %rax, %rdx              #count for printf (2nd argument)
    mov     $msg, %rdi              #format for printf(1st argument)
    mov     %r8, %rsi               #ch for printf (3rd argument)

    xor     %rax, %rax              #reset %rax for printf output

    call    printf                  #print the frequency value of the ch in string
#Case U
    mov     %ch,%cl
    mov     $0, %rax                #initialize count to 0
    call    FREQ

    mov     %rax, %rdx              #count for printf (2nd argument)
    mov     $msg, %rdi              #format for printf(1st argument)
    mov     %r8, %rsi               #ch for printf (3rd argument)

    xor     %rax, %rax              #reset %rax for printf output

    call    printf                  #print the frequency value of the ch in string

    jmp done


done: 

    ret

子程序:

    .text 
    .globl  FREQ



FREQ:   
    #subprogram body
Start:
    cmpb    $0,8(%rsi)              #check for end of the string
    je      donefreq

loopfreq:
    cmp     %cl, 8(%rsi)            #compare first string char with vowel 
    je      incrementstring         #if equal - jump to increment_string
    add     $1, %rsi                #if not - increment string
    jmp     Start                   #jump to loop to check for end of string status/next char

incrementstring:
    add     $1, %rsi                #increment to next string character
    add     $1, %rax                #add 1 to frequency of character
    jmp     Start

donefreq:
    ret

不确定为什么会这样。 - 我希望调试提供更多信息:(

有没有人知道为什么会这样?我完全遵循了被调用函数的笔记轮廓,所以我不知道问候在被调用者的位置

1 个答案:

答案 0 :(得分:3)

您不应该使用%rsp作为指向字符串的指针。您正在破坏堆栈中的返回地址,因此您的ret指令会尝试跳转到某个虚假地址。使用%rsi或其他通用寄存器。堆栈指针不是您可以根据需要使用的寄存器。