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指令的区别?我在阅读汇编时遇到了一些麻烦[重复]
需要帮助使用 masm 以 80x86 汇编语言连接两个字符串
Android 逆向x86 汇编 ( 参考资料 | Intel 官方的文档 | x86 汇编中文文档 | 汇编指令查询器 )
Android 逆向x86 汇编 ( 参考资料 | Intel 官方的文档 | x86 汇编中文文档 | 汇编指令查询器 )