2012-10-23 59 views
1

我想將字符串添加到數組中,以便以後從數組中打印,這就是我所擁有的。我錯過了什麼?以彙編語言打印字符串數組

INCLUDE Irvine32.inc 
.data 
array dword 20 dup (0) 
str1 byte 20 dup (0) 
temp dword ? 
n dword ? 
count dword 0 

mes1 db "press 1 to add an element, 2 to print, 3 to quit ", 0 

.code 
main PROC 

start: 
    lea edx, mes1 
    call writestring 
    call readdec 
    cmp eax, 1 
    je add1 
    cmp eax, 2 
    je print2 
    cmp eax, 3 
    je stop 

add1: 
    call readin 
    jmp done 

print2: 
    call print 
    jmp done 

done: 
    jmp start 

stop: 
    exit 

main ENDP 

readin proc 
    lea edx, str1 
    mov ecx, sizeof str1 
    call readstring 

    mov ebx, count 
    mov eax, [array] 
    mov temp, eax 
    add temp, ebx 
    lea esi, temp 
    mov ebx, [str1] 
    mov [esi], ebx 

readin endp 

print proc 
    mov esi, 0 
    mov ecx, n 

    @@do: 
     mov eax, Array[esi] 
     call writedec 
     call crlf 
     add esi, 4 
     @@while: loop @@do 

     ret 
print endp 
END main 
+0

您正在使用哪種彙編程序?它使用什麼語法獲取標籤的地址,而不是在那裏讀寫內存?你似乎使用'標籤'與'[標籤]'不一致... –

+0

我正在使用Microsoft Visual Studio 10.據我所知,獲取地址的語法是[標籤],但我剛開始嘗試最近搞清楚了,所以我可能是錯的。我想我看到[str1]應該是str1的問題,所以我會編輯它。 – user1769457

+0

我在Visual Studio中遇到錯誤,指令操作數必須與readin過程中的'mov ebx,[str1]'一致。 – user1769457

回答

0

最簡單的解決方案是創建一個字節數組,它包含一行中以空字符結尾的字符串。這不是真正的「字符串數組」。成分:一個大緩衝區和一個指向該緩衝區有效部分末尾的指針。

INCLUDE Irvine32.inc 

.DATA 

    arrayptr DWORD OFFSET array 
    array  BYTE 4096 DUP (?) 

    mes1  BYTE 10, "press 1 to add an element, 2 to print, 3 to quit ", 0 

.CODE 

readin PROC 
    mov edx, arrayptr   ; Argument for ReadString: Pointer to memory 
    mov ecx, 10     ; Argument for ReadString: maximal number of chars 
    call ReadString    ; Doesn't change EDX 
    test eax, eax    ; EAX == 0 (got no string) 
    jz done      ; Yes: don't store a new arrayptr 
    lea edx, [edx+eax+1]  ; EDX += EAX + 1 
    mov arrayptr, edx   ; New pointer, points to the byte where the next string should begin 
    done: 
    ret 
readin ENDP 

print PROC 
    lea edx, array    ; Points to the first string 

    L1: 
    cmp edx, arrayptr   ; Does it point beyond the strings? 
    jae done     ; Yes -> break 

    call WriteString   ; Doesn't change EDX 
    call Crlf     ; Doesn't change EDX 

    scan_for_null: 
    inc edx 
    cmp BYTE PTR [edx], 0  ; Terminating null? 
    jne scan_for_null   ; no -> next character 
    inc edx      ; Pointer to next string 

    jmp L1 

    done: 
    ret 
print ENDP 

main PROC 
start: 
    lea edx, mes1 
    call WriteString 
    call ReadDec 
    cmp eax, 1 
    je add1 
    cmp eax, 2 
    je print2 
    cmp eax, 3 
    je stop 
    jmp next     ; This was missing in the OP 

add1: 
    call readin 
    jmp next     ; Just a better name than in the OP 

print2: 
    call print 
    jmp next     ; Just a better name than in the OP 

next:       ; Just a better name than in the OP 
    jmp start 

stop: 
    exit 
main ENDP 

END main 

陣列中的所有的元件具有通常相同的尺寸(在上述示例中字節)。所以元素的位置可以用索引來索引和容易地計算。確定字節數組中某個字符串的位置並不容易。必須從頭開始掃描數組以查找字符串終止零(請參閱塊scan_for_null)。 「字符串數組」實際上是指向字符串的指針數組:

INCLUDE Irvine32.inc 

.DATA 

    bufptr  DWORD OFFSET buf ; Pointer to the beginning of free buffer 
    buf   BYTE 4096 DUP (?) ; Space for 4096 characters 
    array  DWORD 20 DUP (?) ; Space for 20 pointers 
    arrayindex DWORD 0    ; Index of the next free pointer in array 

    mes1  BYTE 10, "press 1 to add an element, 2 to print, 3 to quit ", 0 

.CODE 

readin PROC 
    mov edx, bufptr    ; Argument for ReadString: Pointer to memory 
    mov ecx, 10     ; Argument for ReadString: maximal number of chars 
    call ReadString    ; Doesn't change EDX 
    test eax, eax    ; EAX == 0 (got no string) 
    jz done      ; Yes: don't change bufptr 
    mov esi, arrayindex 
    mov [array + esi * 4], edx ; Store the actual bufptr 
    inc arrayindex 
    lea edx, [edx+eax+1]  ; EDX += EAX + 1 (new bufptr) 
    mov bufptr, edx    ; New pointer, points to the byte where the next string should begin 
    done: 
    ret 
readin ENDP 

print PROC 
    xor esi, esi    ; First index 

    L1: 
    cmp esi, arrayindex   ; Beyond last index? 
    jae done     ; Yes -> break 

    mov edx, [array + esi * 4] ; Argument for WriteString: pointer to a null-terminated string 
    call WriteString 
    call Crlf 

    inc esi 
    jmp L1 

    done: 
    ret 
print ENDP 

main PROC 
start: 
    lea edx, mes1 
    call WriteString 
    call ReadDec 
    cmp eax, 1 
    je add1 
    cmp eax, 2 
    je print2 
    cmp eax, 3 
    je stop 
    jmp next 

add1: 
    call readin 
    jmp next 

print2: 
    call print 
    jmp next 

next: 
    jmp start 

stop: 
    exit 
main ENDP 

END main