汇编x86 - 字符串segfault / count子程序的频率不保存返回值

时间:2016-07-15 07:23:49

标签: assembly x86 x86-64 frequency subroutine

所以我在主要的第27行遇到了一个段错误,在我的子程序调用之后,我的%rax保持在值0,当它不应该是。

我试图找出我的子程序没有正确做什么 - 我假设它与我的字节比较,因为我还没有过分熟悉它们。

我还通过printf调用在主程序的第27行获得了段错误。我在这里假设printf函数是预定义的 - 尽管我认为我可能也需要在这里制作printf子程序。

    .text 
    .globl  FREQ



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

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

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

donefreq:
    ret

                .data
string:         .string "This course is about encoding numbers and instructions into binary sequences and designing digital systems to process them."
endofstring:    .space  8
msg:            .string "%c occurs %d times \n"

                .text
                .global main

main:
    sub     $8,%rsp                 #stack alignment
    mov     $string,%rsi            #rsi = string storage
    mov     $0x61, %r8              #storage of a 
    mov     $0x65, %r9              #storage of e
    mov     $0x69, %r10             #storage of i
    mov     $0x6F, %r11             #storage of o
    mov     $0x75, %r12             #storage of u


#Case A
    mov     %r8,%rcx
    mov     $0, %rax                #initialize count to 0
    call    FREQ                    #Generate %rax value for count
    mov     %rax, %rdx              #2nd argument for print function - number of 
    mov     $msg, %rdi              #1st argument for print function - format for print function
    mov     %r8, %rsp           #3rd argument for print function - char

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


#Case E
    mov     %r9,%rcx
    mov     $0, %rax                #initialize count to 0
    call    FREQ
    mov     $msg, %rdi              #1st argument for print function - format for print function
    mov     %r9, %rsp           #3rd argument for print function - char
    mov     %rax, %rdx              #2nd argument for print function - number of 
    call    printf                  #print the frequency value of the ch in string

#Case O
    mov     %r10,%rcx
    mov     $0, %rax                #initialize count to 0
    call    FREQ
    mov     $msg, %rdi              #1st argument for print function - format for print function
    mov     %r10, %rsp          #3rd argument for print function - char
    mov     %rax, %rdx              #2nd argument for print function - number of 
    call    printf                  #print the frequency value of the ch in string

#Case I
    mov     %r11,%rcx
    mov     $0, %rax                #initialize count to 0
    call    FREQ
    mov     $msg, %rdi              #1st argument for print function - format for print function
    mov     %r11, %rsp          #3rd argument for print function - char
    mov     %rax, %rdx              #2nd argument for print function - number of 
    call    printf                  #print the frequency value of the ch in string
#Case U
    mov     %r12,%rcx
    mov     $0, %rax                #initialize count to 0
    call    FREQ
    mov     $msg, %rdi              #1st argument for print function - format for print function
    mov     %r12, %rsp          #3rd argument for print function - char
    mov     %rax, %rdx              #2nd argument for print function - number of 
    call    printf                  #print the frequency value of the ch in string

    jmp done




done: 
    add     $8, %rsp                #reset stack alignment
    ret

程序计算句子中每个元音的数量 - 输出打印语句中该字符的数量。

1 个答案:

答案 0 :(得分:1)

至少存在以下问题(我假设它适用于x86-64):

  1. 第二个参数必须在%rsi
  2. 中传递
  3. 第三个参数必须在%rdx
  4. 中传递
  5. 对于printf,您需要将%rax设置为使用的向量寄存器数量(在您的情况下为0),例如与xor %rax, %rax
  6. printf是一个带有可变参数列表的C函数。调用此类函数的约定可以在ABI第3.5.7节中找到:

      

    当调用带有变量参数的函数时,%rax必须设置为向量寄存器中传递给函数的浮点参数总数。