组装(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)数组操作的主要内容,如果未能解决你的问题,请参考以下文章

MASM Assembly 中的数组(非常困惑的初学者)

MASM汇编 - REAL4浮点指令

宏打印存储在字节中的值。组装masm

在 win32 上用 MASM 组装的程序没有控制台输出

组装原型说明

MASM 数组不循环