Untuk menentukan apakah bilangan heksadesimal genap, program akan membagi bilangan tersebut dengan 2 dan sisanya harus sama dengan nol. Jika tidak, maka itu adalah bilangan ganjil. Awalnya, rencana saya adalah saya memiliki variabel atau register yang akan bertambah ketika heksadesimal terbukti genap. Kemudian setelah itu saya hanya akan mengurangi jumlah genap. sampai lima untuk mendapatkan jumlah no ganjil. Tetapi karena saya harus menggunakan tiga register untuk menyimpan dividen dan pembagi (AX & BX), ditambah satu lagi untuk penghitung array (CX), saya kehabisan register untuk menyimpan nilai "penghitung genap ".

Saya merevisi program sehingga masih dapat memenuhi instruksi (lihat judul). Kali ini, program akan menampilkan karakter E untuk genap dan O untuk ganjil. Masalah saya sekarang adalah program hanya mengenali hingga item array kedua, artinya nilai SI tetap sama dan tidak bertambah setelah item array kedua. Ini membuat output dari program EOOOO bukan EOOOE.

Pertanyaan saya adalah: 1.) Bagaimana saya akan menambah nilai SI dari memorinya dan meneruskannya ke AX untuk dibagi 2.) Apakah mungkin untuk membuat rencana awal saya berhasil? Jika ya, register apa yang dapat saya gunakan untuk mengadakan "penghitung genap"

Berikut kodenya:

.MODEL SMALL
 
READ MACRO MSG
    MOV AH,0AH
    LEA DX,MSG
    INT 21H
ENDM

SET MACRO MSG
    MOV AH,09H
    LEA DX,MSG
    INT 21H
ENDM

.DATA 
 
 CR EQU 0DH
 LF EQU 0AH
    ARR DW 100h,16Fh,191h,10Fh,120h 
    MSG1 DB CR,LF,"Array of 16 bit hexadecimals: 100h,16Fh,191h,10Fh,120h$"
    MSG2 DB CR,LF,"E=EVEN   O=ODD$"
    
    NUMERALEVEN DB CR,LF,"E$"
    NUMERALODD DB CR,LF,"O$"
    
 COUNT EQU 5H
 

DATA ENDS

    
.CODE
ASSUME CS:CODE,DS:DATA 

START:
        MOV AX,DATA
        MOV DS,AX
    
        SET MSG1
        SET MSG2
        
        MOV SI,OFFSET ARR
        MOV CL,COUNT
        MOV AX,[SI]
        
        MOV DX,0000

                
CHECK:  
        MOV DX,0000                       
        MOV BH,00
        MOV BL,02H     ;divide by 2  
        DIV BX         
        
        CMP DX,0       ;checks if there is a remainder by comparing the remainder to 0
        JE EVEN
        JNE ODD        
        
        
EVEN:   
        SET NUMERALEVEN
        
        MOV DX,00 
        DEC CL
        MOV AX,[SI+1]
        MOV [SI],AX 
        
        CMP CL,0
        JNZ CHECK
        
         
ODD:    
        SET NUMERALODD
        
        DEC CL

        MOV AX,00
        MOV AX,[SI+1]
        MOV [SI],AX
        
        CMP CL,0
        JNZ CHECK
                
CODE ENDS
END START 
0
jessa 12 Mei 2021, 08:25

1 menjawab

Jawaban Terbaik

Ini membuat output dari program EOOOO bukan EOOOE.

Anda tampaknya tidak sepenuhnya menyadari apa yang sebenarnya dilakukan oleh instruksi berikut dalam kode Anda:

MOV AX,00
MOV AX,[SI+1]
MOV [SI],AX

Instruksi pertama tidak berguna karena instruksi kedua akan menimpa nilai AX.

Karena larik Anda terdiri dari nilai 16-bit dan CPU x86 menggunakan pengalamatan byte (seperti kebanyakan tetapi tidak semua CPU), nilai kedua akan disimpan di alamat [SI+2], bukan di [SI+1].

Dengan membaca [SI+1], Anda membaca beberapa nilai (tidak masuk akal) yang dapat dihitung dari dua angka pertama dalam array.

Dan menggunakan instruksi terakhir Anda menimpa nomor pertama dalam array, yang tidak masuk akal bagi saya.

Anda tidak pernah mengubah register SI. Tanpa memodifikasi register SI, Anda tidak akan pernah membaca nilai nanti dalam array!

Jadi apa yang dilakukan program Anda adalah sebagai berikut:

   Initially, your array contains the values 100h,16Fh,...
   You check the value 100h (if it is even or odd)
 MOV AX,[SI+1]   loads 6F01h into AX
 MOV [SI],AX     overwrites the first value in the array by 6F01h
   You check the value 6F01h (if it is even or odd)
 MOV AX,[SI+1]   loads 6F6Fh into AX
 MOV [SI],AX     overwrites the first value in the array by 6F6Fh
   You check the value 6F6Fh (if it is even or odd)
 MOV AX,[SI+1]   loads 6F6Fh into AX
 MOV [SI],AX     has no effect ...
   ... because the first element of the array is already 6F6Fh
 MOV AX,[SI+1]   loads 6F6Fh into AX
   ...
 MOV AX,[SI+1]   loads 6F6Fh into AX
   ...
 MOV AX,[SI+1]   loads 6F6Fh into AX
   ...

Jadi pertama kali program Anda memeriksa apakah 100h genap atau ganjil. Ini adalah apa yang Anda inginkan.

Kedua kalinya memeriksa apakah 6F01h genap atau ganjil. Dan yang ketiga, keempat, kelima ... kesepuluh ... keseratus, ia memeriksa apakah 6F6Fh genap atau ganjil. Inilah yang mungkin tidak Anda inginkan.

Untuk menentukan apakah bilangan heksadesimal genap, program akan membagi bilangan tersebut dengan 2 dan sisanya harus sama dengan nol.

Jika Anda bekerja dengan angka desimal (tanpa komputer) dan ingin memeriksa apakah suatu angka habis dibagi sepuluh - apakah Anda juga akan membagi angka tersebut dengan sepuluh dan melihat sisanya?

Tidak. Anda akan melihat angka terakhir dan memeriksa apakah itu nol.

Anda dapat melakukan ini di semua sistem angka:

Dalam sistem terner, suatu bilangan habis dibagi 3 jika angka terakhirnya nol; dalam sistem heksadesimal itu habis dibagi 16 jika digit terakhir adalah nol. Dan dalam sistem biner habis dibagi dua jika digit terakhir (= bit) adalah nol.

Anda dapat menggunakan instruksi TEST untuk memeriksa apakah bit adalah nol atau satu:

Instruksi TEST xxx, 1 memeriksa apakah bit terakhir dari nilai xxx adalah 0 dan menyetel flag nol jika ini masalahnya (dan menghapus flag nol sebaliknya). Ini berarti bahwa instruksi JZ (yang sama dengan JE) akan melompat jika bit itu nol. Dan JNZ (JNE) akan melompat jika bit itu adalah satu.

Jadi Anda dapat mengganti kode berikut dengan instruksi TEST AX, 1:

MOV DX,0000
MOV BH,00
MOV BL,02
DIV BX
CMP DX,0

Dan Anda bahkan dapat menggunakan TEST WORD [SI], 1 untuk langsung memeriksa bit dalam angka dari array, sehingga Anda bahkan tidak perlu menggunakan MOV AX, [SI] untuk memuat nilai ke dalam register AX.

3
Martin Rosenau 12 Mei 2021, 07:59