[英]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.