组装(masm)数组操作
Posted
技术标签:
【中文标题】组装(masm)数组操作【英文标题】:Assembly (masm) array manipulation 【发布时间】:2016-03-14 17:58:09 【问题描述】:组装新手,非常坚持如何做到这一点:
我有一个用户指定的数组。用户输入长度和字符。我的问题是我需要将所有元音移到数组的开头。
这是我目前的进度
INCLUDE Irvine32.inc
.data
ProgInfo BYTE " ",0Ah
BYTE "------------------------------------------------------",0Ah
BYTE "This program will reorder an array of characters",0Ah
BYTE "all vowels will be moved to the beginning of the array",0Ah
BYTE "------------------------------------------------------",0Ah
BYTE " ",0
Prompt1 BYTE "Please enter the number of characters to be inputed: ",0
NChars DWORD ? ;Unitialized for user input
myarray BYTE ?
Prompt2 BYTE "Please enter a string of characters: ",0
Reordered BYTE " ",0Ah
BYTE "The reordered array is: ",0
.code
main PROC
mov edx, OFFSET ProgInfo
call WriteString
mov edx, OFFSET Prompt1 ;ask for total characters
call WriteString
call ReadInt ;read as integer
mov Nchar, eax
mov edx, OFFSET Prompt2 ;ask for the string of characters
call WriteString
mov edx, OFFSET myarray
mov ecx, NChars
call ReadString
exit
main ENDP
END main
考虑使用与此类似的方法来检查循环中的元音,因为它通过数组
VowelCheck:
cmp myarray[edi],'a'
je isVowel
cmp myarray[edi],'A'
je isVowel
cmp myarray[edi],'e'
je isVowel
cmp myarray[edi],'E'
je isVowel
cmp myarray[edi],'i'
je isVowel
cmp myarray[edi],'I'
je isVowel
cmp myarray[edi],'o'
je isVowel
cmp myarray[edi],'O'
je isVowel
cmp myarray[edi],'u'
je isVowel
cmp myarray[edi],'U'
je isVowel
【问题讨论】:
你可以有一个包含所有元音的字符串,然后使用repne scasb
来查看是否可以在该字符串中找到当前字符。
我在课堂教科书中搜索了repne scasb
,我发现它会更好,但是我们还没有达到那个点。
@Michael:检查元音的更好方法是use the character as an index into a 32bit-immediate bitmap,在将 ASCII 编码范围移动到字母表中从零开始的索引之后。对于这个问题,您不需要实际排序,只需表现得像插入排序。维护一个指向数组前面元音末尾的元音指针,以及另一个扫描整个数组的指针。当第二个指针找到元音时,进行交换并移动元音指针。
【参考方案1】:
我不确定这是否有帮助,但这里有一个数组和排序的示例。该项目从用户那里获取输入,并在最后一个条目之后将它们按数字顺序排序。
INCLUDE Irvine32.inc
INCLUDELIB Irvine32.lib
.data
str_0 DB 101 DUP(0) ; Reserve space for string inputs
str_1 DB 101 DUP(0)
str_2 DB 101 DUP(0)
str_3 DB 101 DUP(0)
str_4 DB 101 DUP(0)
str_5 DB 101 DUP(0)
str_6 DB 101 DUP(0)
str_7 DB 101 DUP(0)
str_array DWORD OFFSET str_0, ; Store addresses of previous strings in array
OFFSET str_1,
OFFSET str_2,
OFFSET str_3,
OFFSET str_4,
OFFSET str_5,
OFFSET str_6,
OFFSET str_7
; Used by sorting algorithm to know if we swapped on an iteration
swap BYTE 0
.code
main PROC
MOV ECX, 8
MOV EAX, 0
READ_STRINGS:
MOV EDX, [str_array + EAX * 4] ; Get next string address for input
MOV EBX, ECX ; Preserve ECX
MOV ECX, 100 ; Sets max number characters to read in
MOV ESI, EAX ; Preserve EAX
CALL ReadString
MOV EAX, ESI ; restore EAX
INC EAX
MOV ECX, EBX ; Restore ECX
LOOP READ_STRINGS
; Strings are all loaded into memory, time to sort
BEGIN_SORT:
MOV swap, 0 ; Flag for if we make a swap this pass
MOV EAX, 0 ; Current string in str_array
COMPARE_LOOP:
; Loads two string addresses to compare into registers
MOV EDX, [str_array + EAX * 4]
INC EAX
MOV ECX, [str_array + EAX * 4]
MOV EBX, 0 ; Initial location in string
STR_CMP:
; Pull off a byte from the string and load it into EDI
MOVZX EDI, BYTE PTR [EDX + EBX]
; If we hit the end of the first string here, assume we
; are less than the other string
CMP EDI, 0
JE LESS_THAN
MOVZX ESI, BYTE PTR [ECX + EBX] ; Same thing, but for ESI
CMP ESI, 0 ; If we hit the end of the second string here, assume
; we are greater than
JE GREATER_THAN
CMP EDI, ESI ; Else we just do a comparison on the ASCII value
; of the indexed character in the string
JL LESS_THAN
JG GREATER_THAN
INC EBX ; Both characters are equal, move to the next one
; in the strings and do it again
JMP STR_CMP
LESS_THAN:
JMP CHECK_END_SORT ; If the first string is less than the second, they
; are in order, no swapping needed
GREATER_THAN:
DEC EAX
MOV [str_array + EAX * 4], ECX
INC EAX
MOV [str_array + EAX * 4], EDX ; Swap entries
MOV swap, 1
CHECK_END_SORT:
CMP EAX, 7
JNE COMPARE_LOOP ; We are not at the end of str_array yet, loop
; again with next two elements
; If we are here, we are at end of str_array
CMP [swap], 0
JNE BEGIN_SORT ; If we made a swap in this pass of str_array, do
; another pass from the very beginning
; End of sorting
MOV ECX, 8 ; Number of strings to display
MOV EAX, 0 ; Current string to dislay
WRITE_STRINGS:
MOV EDX, [str_array + EAX * 4]
CALL WriteString
Call Crlf
INC EAX
LOOP WRITE_STRINGS
ENDPRGM:
CALL Crlf
CALL WaitMsg
INVOKE ExitProcess, 0
main ENDP
END main
【讨论】:
以上是关于组装(masm)数组操作的主要内容,如果未能解决你的问题,请参考以下文章