x86汇编-句子中字符的频率[重复]

Posted

技术标签:

【中文标题】x86汇编-句子中字符的频率[重复]【英文标题】:x86 Assembly - Frequency of a character in a sentence [duplicate] 【发布时间】:2016-07-14 22:30:29 【问题描述】:
                .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

嘿,

Q:计算给定字符串中元音的数量,并打印出每个元音“aeoiu”的数量和元音。

我遇到了 cmp 编译错误。

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

当试图比较两个字符串的最低有效位时。

有人可以解释我如何将元音字符串的 LSB 与句子字符串的 LSB 进行比较吗?

【问题讨论】:

您缺少即时消息所需的 $。也缺少后缀。应该是cmpb $0, (%rsi)。 PS:cmp %rdi, 0(%rsi) 是错误的,因为它使用了 8 个字节而不是 1 个。 cmpb 0(%rdi), 0(%rsi) 应该可以工作吧?比较两个地址的最低有效位的字节.. 似乎这给了我太多引用错误,就像另一个一样。嗯 是的,只允许 1 个内存操作数。但无论如何,这不是你的意思。您想将内存中的一个字节与零进行比较,作为字符串的结尾,所以cmpb $0, (%rsi) 哦,只允许 1 个内存操作数 - 我不知道。如何比较元音字符串的最低有效位和句子字符串的最低有效位? 显然,将其中一个或另一个加载到寄存器中。 x86-64 有 15 个通用寄存器(不包括rsp),所以使用它们。为什么要比较位?比较字节(ASCII 字符)会更有意义。 【参考方案1】:

您应该分两步完成。

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

或者:

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

这更好,因为程序集不能在一个命令中处理太多引用,就像它通过错误消息告诉你的那样。

%r13 是一个在使用call 函数时不会更改的寄存器,例如:call printf。大多数其他寄存器确实发生了变化,因此很容易知道哪些寄存器没有变化。基本上不变的寄存器是:%r12, %r13, %r14, %r15

【讨论】:

mov (%rcx),%r13 是 8 字节加载,cmpb %r13,(%rsi) 不会组合(b 后缀和 8 字节 %r13 不匹配)。你想做的是movzbl (%rcx), %eax/cmp %al, (%rsi)。 (EAX 可以作为临时使用,因为 printf 在 OP 的循环中破坏了它。虽然我认为他们没有意识到这一点。)为此使用调用保留寄存器是没有意义的,因为原始代码不需要比较后的任一值。

以上是关于x86汇编-句子中字符的频率[重复]的主要内容,如果未能解决你的问题,请参考以下文章

X86中mov和movl指令的区别?我在阅读汇编时遇到了一些麻烦[重复]

x86汇编语言基础

如何在 x86 汇编中编写自己的 atoi 函数

需要帮助使用 masm 以 80x86 汇编语言连接两个字符串

Android 逆向x86 汇编 ( 参考资料 | Intel 官方的文档 | x86 汇编中文文档 | 汇编指令查询器 )

Android 逆向x86 汇编 ( 参考资料 | Intel 官方的文档 | x86 汇编中文文档 | 汇编指令查询器 )