가장 간단한 해결 방법은 행에 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
어떤 어셈블러를 사용하고 있습니까? 그곳에서 메모리를 읽거나 쓰는 것과는 대조적으로 레이블의 주소를 가져 오는 데 어떤 구문을 사용합니까? 당신은'label' 대'[label]'을 일관되게 사용하지 않는 것 같습니다 ... –
저는 Microsoft Visual Studio 10을 사용하고 있습니다. 주소를 얻는 구문은 제 지식으로는 알 수 없지만 최근에 이것을 알아 내서 잘못 될 수 있습니다. 나는 [str1]이 str1이어야한다는 문제점을 보았 기 때문에 나는 그것을 편집 할 것이다. – user1769457
Visual Studio에서 "명령 피연산자가 같은 크기 여야합니다"라는 오류가 나타납니다. 읽기 절차에 'mov ebx, [str1]'이 (가) 있습니다. – user1769457