这是它应该打印的内容
输入以某种语言编写的字符串:“如果土拨鼠会扔木头,它会扔多少木头?”
a:2 B:0 c:10 d:6 e:0 f:1 g:0 h:6 i:1 j:0 k:4 l:2 m:1 n:0 o:11 p:0 q:0 r:0 s:0 t:0 u:7 v:0 w:6 x:0 y:0 z:0观察员
然而我的只是打印:输入以某种语言编写的字符串:“如果土拨鼠会扔木头,它会扔多少木头?”
a:2 B:0 c:10 d:6 e:0 f:1 g:0 h:6 i:1 j:0 k:4 l:2 m:1 n:0 o:11 p:0 q:0 r:0 s:0 t:0 u:7 v:0 w:6 x:0 y:0 z:0
%include "asm_io.inc"
section .data
msg db "Enter a string written in some language: ", 0
section .bss
counters resd 26 ; an array of 26 counters, each storing a 4-byte value
sorted resd 26 ; an array of 26 letters, sorted by decreasing number of occurrences
input resd 1 ; to store the input character
section .text
global asm_main
asm_main:
; setup
enter 0, 0
pusha
; print prompt
mov eax, msg
call print_string
; loop to count characters
mov ebx, counters
loop:
call read_char ; read input character
cmp eax, 10 ; check if end of input (newline character)
je end ; if newline character, exit loop
cmp eax, 97 ; check if lowercase
jl upper_case ; if less than 97, ignore
cmp eax, 122 ; check if lowercase
jg not_alpha ; if greater than 122, check uppercase
sub eax, 97 ; ASCII value subtract by 97 to get index
jmp update_counter
lowercase_counter:
cmp eax, 0
je next
add ebx, 4
dec eax
jmp lowercase_counter
upper_case:
cmp eax, 65 ; check if uppercase
jl not_alpha ;if less than 65, ignore it
cmp eax, 90 ; check if uppercase
jg not_alpha ; if greater than 90, ignore it
sub eax, 65 ; ASCII value subtract by 65 to get index
jmp update_counter
uppercase_counter:
cmp eax, 0
je next
add ebx, 4
dec eax
jmp uppercase_counter
not_alpha:
; ignore non-letter characters
jmp loop
update_counter:
inc dword [ebx+eax*4]
mov ebx, counters
jmp loop
next:
mov ebx, counters
jmp loop
end:
; print character counts
mov ebx, counters
mov ecx, 97
loop2:
cmp ecx, 122
jg end2
mov eax, ecx
call print_char
mov eax, 58
call print_char ; print the colon character
mov eax, [ebx]
call print_int
mov eax, 32
call print_char
inc ecx
add ebx, 4
jmp loop2
; sort letters by decreasing count
mov eax, sorted
mov ebx, counters
mov ecx, 26
outer_loop:
mov edx, [ebx]
mov [eax], edx
add eax, 4
add ebx, 4
loop outer_loop
mov eax, sorted
mov ebx, 24
sort_loop:
mov ecx, 0
inner_loop:
mov edx, [eax] ; move the value of the first element of the array into edx
mov ebx, [eax + 4] ; move the value ofthe second element of the array into ebx
cmp edx, ebx ; compare the two values
jge skip_swap ; if the first value is greater than or equal to the second value, skip the swap
mov [eax], ebx ; move the second value to the first element of the array
mov [eax + 4], edx ; move the first value to the second element of the array
skip_swap:
add eax, 4 ; move to the next pair of elements in the array
loop inner_loop ; repeat until all pairs have been compared and swapped (if necessary)
dec ebx ; move to the next element in the array, excluding the last element since it is already sorted
cmp ebx, 0 ; check if we have reached the beginning of the array
jge sort_loop ; if not, repeat the sorting process for the remaining unsorted elements
; print sorted letters and their counts
call print_nl
mov eax, sorted
mov ebx, counters
mov ecx, 26
print_sorted:
cmp ecx, 0
jle end2
mov edx, [eax]
add eax, 4
sub ecx, 1
cmp edx, 0
je print_sorted ; skip printing if the count is 0
add edx, 97
mov eax, edx
call print_char
mov ebx, 58 ; store the ASCII code for ":" in ebx
call print_char ; print ":"
mov eax, [ebx + (edx - 97) * 4] ; retrieve the count using the letter's ASCII value
call print_int
call print_nl
jmp print_sorted
end2:
call print_nl
popa ; clean up
mov eax, 0 ; clean up
leave ; clean up
ret ; clean up
1条答案
按热度按时间zyfwsgd61#
为什么不打印?
您的程序没有输出“ocuwhdklamifzyxvtsrqpnjgeb”,因为您在打印完计数器之后已经跳到了末尾。
现在,上面的错误是一种祝福,因为如果排序代码被允许执行,它将被证明包含一个无限循环。您初始化ECX=0,然后使用LOOP指令。这段代码将循环40亿次!
此外,您打算将EBX寄存器用于两个完全不同的目的:一次作为某种计数器,一次作为数组元素。这正是崩溃的组成部分。为什么不使用更多不同的寄存器呢?你还有ESI,EDI和EBP可以玩。
您试图使用计数器对数组副本进行降序冒泡排序。如果不采取预防措施,您将失去与字母表中字母的任何连接!
就我个人而言,我会将字符包含在要排序的记录中的某个地方,但只使用实际计数来确定顺序:
现在,sorted 处的内存如下所示:
因此,您需要编写 * 一个简单的循环 *,从每个双字中检索第二个字节,然后将其打印出来。
不要使用当前版本的 print_sorted,它包含许多错误!