2

So I'm running into a segfault on line 27 of main and after my subprogram call my %rax remains at the value 0 when it shouldn't be.

I'm trying to figure out what my subprogram isn't doing correctly - I'm assuming its with my byte comparisons as I'm not overly familiar with them yet.

I'm also getting a segfault on line 27 of the main program with the printf call. I'm assuming here that the printf function is predefined - though I think I might be needing to make a printf subprogram as well here.

Sub

    .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

main

                .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

The program counts the number of each vowel in the sentence - outputs the number of that character in a print statement.

Jester
  • 56,577
  • 4
  • 81
  • 125
Egyptian_Coder
  • 63
  • 1
  • 10
  • `mov %r9, %rsp` is a typo presumably. You want `mov %r9, %rsi` there and at all the other places. You have other errors too, but this is the one you asked about :) – Jester Jul 15 '16 at 11:03
  • That is definitely a typo :( Oh gosh. thank you. Hopefully the other errors will be easy fixes! – Egyptian_Coder Jul 15 '16 at 17:06
  • @Jester Hey Jester, would you happen to know how I could check values in a subprogram using GDB? I compile with `gcc -g -o runtest main.s count.s` and then, `gdb runtest` with breaks at the lines before and after the call line but when I get to the `call count` line it skips right over it. Turns out its just `break count.s:1` for subprogram breaks. Thanks! – Egyptian_Coder Jul 15 '16 at 19:41
  • You need to use the `stepi` not the `nexti` command. Yeah placing breakpoint on your subprogram also works of course. – Jester Jul 15 '16 at 19:44
  • I've run into a segfault in my subprogram - The issue I believe is that its forever looping due to this line `cmp %rcx, (%rsp)` - Would you know why its giving me an error? @Jester – Egyptian_Coder Jul 15 '16 at 20:34
  • 1
    Yes you are comparing 8 bytes instead of 1. – Jester Jul 15 '16 at 20:35
  • would `cmpb` do the trick? – Egyptian_Coder Jul 15 '16 at 20:47
  • Looks like that won't work with %rcx - the 8 bytes are from register %rcx that im comparing to the most significant bit of %rsp. I need a way to only get 1 byte from %rcx. How do you do this? – Egyptian_Coder Jul 15 '16 at 21:02
  • Use `%cl`? You might want to familiarize yourself with the register set ;) – Jester Jul 15 '16 at 21:19
  • %cl is an 8-bit register (1 byte) so If i throw the ascii value of a into %cl instead of %rcx, then the `cmp` should compare bytes now. I'll give this a shot, hopefully I've understood what you've suggested correctly, thank you Jester. ;) – Egyptian_Coder Jul 15 '16 at 21:29

1 Answers1

1

There are at least the following issues (I assume it is for x86-64):

  1. The second argument must be passed in %rsi.
  2. The third argument must be passed in %rdx.
  3. For printf you need to set %rax to the number of vector registers used (in your case 0), e.g. with xor %rax, %rax.

printf is a C function with variable argument list. The convention to call such function can be found in ABI section 3.5.7:

When a function taking variable-arguments is called, %rax must be set to the total number of floating point parameters passed to the function in vector registers.

ead
  • 32,758
  • 6
  • 90
  • 153