2016-07-14 6 views
-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 

Эй,x86 Сборка - Частота характера в предложении

Q: Подсчитать количество гласных букв в заданной строке и распечатать номер и гласный для каждого из гласных букв «aeoiu».

Я столкнулся с ошибкой компиляции cmp.

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

при попытке сравнить две строки младших значащих бит.

Может кто-нибудь объяснить, как я мог бы сравнить LSB строки гласного с LSB строки предложения?

+0

Вам не хватает '$', который требуется для непосредственных пользователей. Также отсутствует суффикс. Должно быть 'cmpb $ 0, (% rsi)'. PS: 'cmp% rdi, 0 (% rsi)' неверно, потому что он использует 8 байтов вместо 1. – Jester

+0

'cmpb \t 0 (% rdi), 0 (% rsi)' должен работать правильно? сравнивает байты наименее значимых битов обоих адресов .. похоже, что это дало мне слишком много ошибок ссылок, как это делал другой. hmm –

+0

Да, допускается только 1 операнд памяти. Но это не значит, что вы имели в виду. Вы хотели сравнить байт из памяти с нулем, для конца строки, поэтому 'cmpb $ 0, (% rsi)'. – harold

ответ

0

Вы должны сделать это в два этапа.

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

Или:

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

Это лучше, потому что сборка не может обрабатывать слишком много ссылок в одной команде, как он говорит вам, с сообщением об ошибке.

%r13 - это регистр, который не изменяется при использовании функции call: call printf. Большинство других регистров действительно меняются, поэтому удобно знать, какие регистры не меняются. В основном регистры, которые не меняются: %r12, %r13, %r14, %r15.

+0

'mov (% rcx),% r13' - это 8-байтовая нагрузка, а' cmpb% r13, (% rsi) 'не будет собираться (несоответствие между' b' suffix и 8-байтным '% r13'). То, что вы пытаетесь сделать, это 'movzbl (% rcx),% eax' /' cmp% al, (% rsi) '. (EAX доступен как временный, потому что 'printf' сжимает его в цикле OP. Хотя я думаю, что они этого не понимают.) Нет смысла использовать регистр с сохранением вызова для этого, потому что исходный код не нужен либо значение после сравнения. –