-1
                .data
ch:             .string "aeiou"     #ascii char
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     $ch,%rbx                #rbx = character storage
    mov     0(%rbx),%rdi            #character argument 
    mov     8(%rbx),%rsi            #string argument

loop:
    mov     $0, %rax                #initialize count to 0
    mov     0(%rdi),%rcx            #move first char into %rcx
    cmp     $0,0(%rbx)              #check for end of ch input
    je      done                    #jump to done if end of ch string

    call    FREQ                    #return the freq of ch in string and place in %rax

    mov     $msg, %rdi              #1st argument for print function - format for print function
    mov     0(%rbx), %rsp           #3rd argument for print function - char
    mov     %rax, %rdx              #2nd argument for print function - number of chars

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

    add     $1, %rdi                #increment vowel

    jmp     loop


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

loopfreq:
    cmpb    (%rcx), 0(%rsi)         #compare first string char with ch 
    je      increment_string        #if equal - jump to increment_string
    add     $1, %rsi                #if not - increment string
    jmp     loop                    #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


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

Hey,

Q: Count the number of vowels in the given string and print out the number and the vowel for each of the vowels "aeoiu".

I'm running into a cmp compile error.

 main.s:41: Error: too many memory references for `cmp'

when trying to compare the two strings least significant bits.

Can someone explain how I could go about comparing the LSB of the vowel string to the LSB of the sentence string?

Egyptian_Coder
  • 63
  • 1
  • 10
  • You are missing a `$` which is required for immediates. Also missing suffix. Should be `cmpb $0, (%rsi)`. PS: `cmp %rdi, 0(%rsi) ` is wrong because it uses 8 bytes instead of 1. – Jester Jul 14 '16 at 22:32
  • `cmpb 0(%rdi), 0(%rsi) ` should work then right? compares the bytes of the least significant bits of both addresses.. seems like that gave me a too many references error just like the other one did. hmm – Egyptian_Coder Jul 14 '16 at 22:37
  • Yes, only 1 memory operand allowed. But that's not what you meant anyway. You wanted to compare a byte from memory against zero, for end of string, so `cmpb $0, (%rsi)`. – harold Jul 14 '16 at 22:55
  • Oh only 1 memory operand allowed - I didn't know this. How do I go about comparing the the least significant bit of the vowel string to the least significant bit of the sentence string? – Egyptian_Coder Jul 14 '16 at 23:06
  • Load one or the other into a register, obviously. x86-64 has 15 general purpose registers (not including `rsp`), so use them. And why do you want to compare bits? comparing bytes (ASCII characters) would make more sense. – Peter Cordes Jul 15 '16 at 01:12
  • Downvoted: There are too many bugs in this code for there to be a single useful answer. Only checking for a zero-byte once before entering the loop, and `printf` clobbers `eax`, and much more. – Peter Cordes Sep 22 '17 at 13:17

1 Answers1

0

You should do it in two steps.

mov 0(%rcx),%r13 compb %r13,0(%rsi)

Or:

mov (%rcx),%r13 compb %r13,(%rsi)

This is better because assembly can not handle too much references in one command, like it tells you with the error message.

%r13 is a register that does not change when using a call function like: call printf. Most of the other registers do change, so it is handy to know what registers do not change. Basically the registers that do not change are: %r12, %r13, %r14, %r15.

  • `mov (%rcx),%r13` is an 8-byte load, and `cmpb %r13,(%rsi)` won't assemble (mismatch between `b` suffix and 8-byte `%r13`). What you're trying to do is `movzbl (%rcx), %eax` / `cmp %al, (%rsi)`. (EAX is available as a temporary because `printf` clobbers it in the OP's loop. Although I think they don't realize that.) There's no sense in using a call-preserved register for this, because the original code didn't need either value after the compare. – Peter Cordes Sep 22 '17 at 13:12