2012-10-23 238 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