Arrays 用汇编语言打印字符串数组

Arrays 用汇编语言打印字符串数组,arrays,assembly,printing,masm,irvine32,Arrays,Assembly,Printing,Masm,Irvine32,我正在尝试向数组中添加字符串,以便以后从数组中打印,这就是我所拥有的。我错过了什么 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

我正在尝试向数组中添加字符串,以便以后从数组中打印,这就是我所拥有的。我错过了什么

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

最简单的解决方案是创建一个字节数组,该数组在一行中包含以null结尾的字符串。这实际上不是一个“字符串数组”。成分:一个大缓冲区和一个指向缓冲区有效部分末尾的指针

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\u for\u 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

最简单的解决方案是创建一个字节数组,该数组在一行中包含以null结尾的字符串。这实际上不是一个“字符串数组”。成分:一个大缓冲区和一个指向缓冲区有效部分末尾的指针

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\u for\u 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
vs
[label]
时不一致……我正在使用Microsoft Visual Studio 10。据我所知,获取地址的语法是[label],但我最近才开始尝试解决这个问题,所以我可能是错的。我想我看到了[str1]应该是str1的问题,所以我将对其进行编辑。我在Visual Studio中遇到一个错误,即readin过程中带有“mov ebx,[str1]”的行上的“指令操作数必须相同大小”。那么,您想用
mov ebx[str1]
做什么呢?在这种情况下,汇编器希望访问字节而不是dword。您使用的汇编器是什么?它使用什么语法来获取标签的地址,而不是读/写那里的内存?您似乎在使用
label
vs
[label]
时不一致……我正在使用Microsoft Visual Studio 10。据我所知,获取地址的语法是[label],但我最近才开始尝试解决这个问题,所以我可能是错的。我想我看到了[str1]应该是str1的问题,所以我将对其进行编辑。我在Visual Studio中遇到一个错误,即readin过程中带有“mov ebx,[str1]”的行上的“指令操作数必须相同大小”。那么,您想用
mov ebx[str1]
做什么呢?在这种情况下,汇编程序希望访问字节而不是dword。