从索引访问数组

时间:2016-11-22 19:45:49

标签: assembly x86

所以我在汇编语言x86中遇到问题,我必须提示用户输入一个数字并打印星期几。所以(0 =星期日,1 =星期一..etc)我找到了行索引和列大小,但我遇到了问题。这是我到目前为止的代码。

.model small
.data
message db "Please enter a number between 0 and 6$"
week dword "Sunday___$", "Monday___$", "Tuesday__$", "Wednesday$"
     dword  "Thursday_$", "Friday___$", "Saturday_$"

Rowsize = ($ - week)        

.code
row_index = 1
column_index = 2


main proc
mov ax,@data
mov ds, ax


    mov ah,9
    mov dx,OFFSET message
    int 21h

    mov ah,1
    int 21h

    mov bx, offset week
    add bx, Rowsize * row_index
    mov si, column_index
    mov ax, week[bx + si * TYPE week]

    sub al, 30h
    mov dl, al 
    mov ah, 2
    int 21



    mov ax, 4c00h
    int 21h
    int 20h


main endp
end

例如

; The following example locates the value at row 1, column2


.model small
 .data
tableB Byte 10h, 20h, 30h, 40h, 50h
Rowsize = ($ - tableB)
        Byte 60h, 70h, 80, 90, 0A0h
        Byte 0B0h, 0C0h, 0D0h, 0E0h, 0F0h

.code
main proc
row_ index = 1
column_index = 2

mov ebx, offset tableW   ;table offset
add ebx, Rowsize * row_index  ; row offset
mov esi, column_index
mov al, [ebx + esi]         ; AL = 80h


main endp
end

Months.asm

        .model small
.stack 100h            ;◄■■ STACK!!!
.data
message db "Please enter a number between 0 and 12 : ",0dh,0ah,'$'
week db "January  $",0dh,0ah,'$'
    db  "february $",0dh,0ah,'$'
    db  "  March  $",0dh,0ah ,'$'
    db  "  April   ",0dh,0ah,'$'
    db  "    May $ ",0dh,0ah,'$'
    db "  June   $",0dh,0ah,'$'
    db "  July   $",0dh,0ah,'$'
    db "  August $",0dh,0ah,'$'
     db "September$",0dh,0ah ,'$'
     db " October $",0dh,0ah,'$'
     db "November $",0dh,0ah ,'$'
     db "December$ ",0dh,0ah,'$'

enters db 13 
 bye db 0dh, 0ah, "BYE",0dh, 0ah, '$'

.code                  ;◄■■ CODE!!!
main proc
mov ax,@data
mov ds, ax

L1:
    mov ah,9
    mov dx,OFFSET message
    int 21h


    mov ah,1
    int 21h    

    cmp al, 13 ;When press enter on keyboard should terminate program
    jmp L2

    sub al, 48       




    mov bl, 10       ;◄■■ 9 + DOLLAR SIGN.
    mul bl           ;◄■■ AL * 10.

    mov dx, offset week     
    add dx, ax       ;◄■■ DX POINTS TO THE PROPER DAY.

    mov ah, 9
    int 21h          ;◄■■ 21H, NOT 21.
    jmp L1

L2: mov dx, offset bye
    mov ah,9
    int 21h

    mov ax, 4c00h
    int 21h

main endp
end

1 个答案:

答案 0 :(得分:1)

我的代码中有一些错误,我用箭头指出(anf fixed),也乘以9(实际上它是10,因为每一天都以美元符号结束):

.model small
.stack 100h            ;◄■■ STACK!!!
.data
message db "Please enter a number between 0 and 6 : $"
week db "Sunday___$", "Monday___$", "Tuesday__$", "Wednesday$"
     db  "Thursday_$", "Friday___$", "Saturday_$"
.code                  ;◄■■ CODE!!!
main proc
mov ax,@data
mov ds, ax

    mov ah,9
    mov dx,OFFSET message
    int 21h

    mov ah,1
    int 21h          ;◄■■ NUMBER RETURNS IN AL.
    sub al, 48       ;◄■■ CONVERT CHAR TO DIGIT.

    mov bl, 10       ;◄■■ 9 + DOLLAR SIGN.
    mul bl           ;◄■■ AL * 10.

    mov dx, offset week     
    add dx, ax       ;◄■■ DX POINTS TO THE PROPER DAY.

    mov ah, 9
    int 21h          ;◄■■ 21H, NOT 21.

    mov ax, 4c00h
    int 21h

main endp
end

编辑#1:使用索引为每天的数组

.model small
.stack 100h
.data
message db "Please enter a number between 0 and 6 : $"
week db "Sunday$", "Monday$", "Tuesday$", "Wednesday$"
     db "Thursday$", "Friday$", "Saturday$"
offs dw 0,7,14,22,32,41,48 ;◄■■ INDEXES OF DAYS.
.code
main proc
mov ax,@data
mov ds, ax

    mov ah,9
    mov dx,OFFSET message
    int 21h

    mov ah,1
    int 21h
    sub al, 48
    xor ah, ah     ;◄■■ CLEAR AH, SO AX=AL.

    mov si, ax ;◄■■ TRANSFER NUMBER TO AN INDEX REGISTER.      
    shl si, 1  ;◄■■ SI*2, BECAUSE EACH INDEX IS DW.
    add si, offset offs ;◄■■ INDEX OF DAY.
    mov dx, offset week ;◄■■ DAYS OF WEEK.
    add dx, [si] ;◄■■ THE DAY IN WEEK!
    mov ah, 9
    int 21h

    mov ax, 4c00h
    int 21h

main endp
end

编辑#2:显示字母'A'到'L'的月份:

.model small
.stack 100h
.data
message db "Please enter a LETTER between 'A' and 'L' : $"  ;◄■■■
week db ' January ',0dh,0ah,'$'
     db 'february ',0dh,0ah,'$'
     db '  March  ',0dh,0ah,'$'
     db '  April  ',0dh,0ah,'$'
     db '   May   ',0dh,0ah,'$'
     db '  June   ',0dh,0ah,'$'
     db '  July   ',0dh,0ah,'$'
     db ' August  ',0dh,0ah,'$'
     db 'September',0dh,0ah,'$'
     db ' October ',0dh,0ah,'$'
     db 'November ',0dh,0ah,'$'
     db 'December ',0dh,0ah,'$'

bye db 0dh, 0ah, "BYE",0dh, 0ah, '$'

error_msg db 13,10,13,10,'Invalid char.',13,10,13,10,'$'   ;◄■■■

.code
main proc
mov ax,@data
mov ds, ax

L1:
    mov ah,9
    mov dx,OFFSET message
    int 21h

    mov ah,1
    int 21h    

    cmp al, 13 ;When press enter on keyboard should terminate program
    je L2      ;◄■■■ JE = JUMP IF EQUAL (EQUAL TO 13).

;VALIDATE CHAR  ◄■■■
    cmp al, 'l'
    ja  error    ;◄■■■ IF AL >  'l' (JA = JUMP IF ABOVE)
    cmp al, 'A'               
    jb  error    ;◄■■■ IF AL <  'A' (JB = JUMP IF BELOW)
    cmp al, 'L'
    jbe fine     ;◄■■■ IF AL <= 'L' (JBE = JUMP IF BELOW OR EQUAL)
    cmp al, 'a'
    jae fine     ;◄■■■ IF AL >= 'a' (JAE = JUMP IF ABOVE OR EQUAL)
    jmp error    ;◄■■■ ANY OTHER CHAR IS ERROR.
fine:            
;CHECK IF CHAR IS LOWERCASE ('a'..'z') OR UPPERCASE ('A'..'Z') ◄■■■
    cmp al, 'Z'      ;◄■■■
    jb  uppercase    ;◄■■■ IF AL < 'Z'
    sub al, 97       ;◄■■■ 'a' - 97 = 0.
    jmp continue     ;◄■■■ SKIP THE UPPERCASE BLOCK.
uppercase:      
    sub al, 65       ;◄■■■ 'A' - 65 = 0.
continue:

    mov bl, 12       ;◄■■■ 9 + 0D + 0A + $ = 12.
    mul bl           ;◄■■■ AL * 12.

    mov dx, offset week     
    add dx, ax       ;◄■■■ DX POINTS TO THE PROPER MONTH.

    mov ah, 9
    int 21h          ;◄■■■ DISPLAY MONTH.
    jmp L1

error:               ;◄■■■
    mov ah, 9
    mov dx, offset error_msg
    int 21h
    jmp L1

L2: mov dx, offset bye
    mov ah,9
    int 21h

    mov ax, 4c00h
    int 21h

main endp
end