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

어떤 어셈블러를 사용하고 있습니까? 그곳에서 메모리를 읽거나 쓰는 것과는 대조적으로 레이블의 주소를 가져 오는 데 어떤 구문을 사용합니까? 당신은'label' 대'[label]'을 일관되게 사용하지 않는 것 같습니다 ... –

+0

저는 Microsoft Visual Studio 10을 사용하고 있습니다. 주소를 얻는 구문은 제 지식으로는 알 수 없지만 최근에 이것을 알아 내서 잘못 될 수 있습니다. 나는 [str1]이 str1이어야한다는 문제점을 보았 기 때문에 나는 그것을 편집 할 것이다. – user1769457

+0

Visual Studio에서 "명령 피연산자가 같은 크기 여야합니다"라는 오류가 나타납니다. 읽기 절차에 'mov ebx, [str1]'이 (가) 있습니다. – user1769457

답변

0

가장 간단한 해결 방법은 행에 Null 종료 문자열을 포함하는 바이트 배열을 만드는 것입니다. 이것은 실제로 "문자열 배열"이 아닙니다. Ingredients : 큰 버퍼와 그 버퍼의 유효 부분의 끝을 가리키는 포인터.

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 

어레이의 모든 요소는 일반적으로 동일한 크기 (위의 예에서는 바이트)를 갖는다. 따라서 요소의 위치를 ​​색인화하고 해당 색인으로 쉽게 계산할 수 있습니다. 바이트 배열 내부에서 특정 문자열의 위치를 ​​결정하는 것은 쉽지 않습니다. 문자열을 0으로 끝내기 위해 배열을 처음부터 스캔해야합니다 (블록 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