程序集 - 带有子程序的段错误

Assembly - Segfault with subprogram

我正在尝试调试为什么我的子程序出现段错误。

它发生在子程序末尾的 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     [=10=]x61, %ah              #storage of a 
    mov     [=10=]x65, %al              #storage of e
    mov     [=10=]x69, %bh              #storage of i
    mov     [=10=]x6F, %bl              #storage of o
    mov     [=10=]x75, %ch              #storage of u


#Case A
    mov     %ah,%cl                 #1 byte register for cmp later on.
    mov     [=10=], %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     [=10=], %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     [=10=], %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     [=10=], %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     [=10=], %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    [=11=],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     , %rsi                #if not - increment string
    jmp     Start                   #jump to loop to check for end of string status/next char

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

donefreq:
    ret

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

有人知道为什么会这样吗?我完全按照被调用者函数的注释大纲进行操作,所以我不知道问题出在被调用者

您不应使用 %rsp 作为指向字符串的指针。您正在破坏堆栈中的 return 地址,因此您的 ret 指令试图跳转到某个虚假地址。使用 %rsi 或其他通用寄存器。堆栈指针不是一个你可以随意使用的寄存器。