簡體   English   中英

8086 匯編語言程序在 16 位十六進制數數組中查找奇數和偶數的數量

[英]8086 assembly language program to find number of odd and even numbers in an array of 16-bit hexadecimal numbers

為了確定十六進制數是否為偶數,程序會將數字除以 2,余數應為零。 如果不是,那么它是一個奇數。 最初,我的計划是我有一個變量或寄存器,當十六進制被證明是偶數時它會增加。 然后我會減去偶數的數量。 到五得到奇數的數量。 但是由於我必須使用三個寄存器來保存被除數和除數( AX & BX ),再加上另一個用於數組計數器( CX ),所以我用完了寄存器來保存“偶數計數器”的值。

我修改了程序,使它仍然可以滿足指令(見標題)。 這一次,程序將顯示字符E表示偶數, O表示奇數。 我現在的問題是程序最多只能識別第二個數組項,這意味着SI的值保持不變並且在第二個數組項之后不會增加。 這使得程序EOOOO而不是 EOOOE 的EOOOE

我的問題是:1.)我將如何從 memory 中增加SI的值並將其傳遞給AX進行除法 2.)是否有可能使我的初始計划生效? 如果是,我可以使用什么寄存器來保存“偶數計數器”

這是代碼:

.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 

這使得程序EOOOO而不是 EOOOE 的EOOOE

您似乎並不完全了解代碼中的以下說明實際上是做什么的:

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

第一條指令沒有用,因為第二條指令將覆蓋AX的值。

因為您的數組由 16 位值組成,並且 x86 CPU 使用字節尋址(與大多數但不是所有 CPU 一樣),第二個值將存儲在地址[SI+2] ,而不是[SI+1]

通過讀取[SI+1] ,您可以讀取一些(無意義的)值,該值可以從數組中的前兩個數字計算得出。

並使用最后一條指令覆蓋數組中的第一個數字,這對我來說毫無意義。

您永遠不會修改SI寄存器。 如果不修改SI寄存器,您以后將永遠不會讀取數組中的值!

因此,您的程序執行以下操作:

   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
   ...

因此,您的程序第一次檢查100h是偶數還是奇數。 這就是你想要的。

第二次檢查6F01h是偶數還是奇數。 第三、第四、第五……第十……一百次,它檢查6F6Fh是偶數還是奇數。 這可能是你不想要的。

為了確定十六進制數是否為偶數,程序會將數字除以 2,余數應為零。

如果您使用十進制數(沒有計算機)並想檢查一個數字是否可以被十整除 - 您是否還會將該數字除以十並查看余數?

不,您會查看最后一位數字並檢查它是否為零。

您可以在所有數字系統中執行此操作:

在三進制系統中,如果最后一位數字為零,則數字可以被 3 整除; 在十六進制系統中,如果最后一位為零,則可以被 16 整除。 在二進制系統中,如果最后一位(= 位)為零,則它可以被 2 整除。

您可以使用TEST指令檢查某個位是零還是一:

指令TEST xxx, 1檢查值xxx的最后一位是否為 0,如果是則設置零標志(否則清除零標志)。 這意味着如果該位為零,則JZ指令(與JE相同)將跳轉。 如果該位為 1,則JNZ ( JNE ) 將跳轉。

因此,您可以將以下代碼替換為指令TEST AX, 1

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

您甚至可以使用TEST WORD [SI], 1直接檢查數組中某個數字中的位,因此您甚至不需要使用MOV AX, [SI]將值加載到AX寄存器中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM