Найти второе по величине четное число в линейном массиве - Assembler
Формулировка задачи:
Найти второе по величине четное число в линейном массиве
элементы массива - знаковые целые числа размером в слово (не менее 10) ) – должны вводиться с клавиатуры.
И ещё главное чтобы не менялись числа в массиве поэтому код немного странноват
Но иногда появляются ошибки например если все числа одинаковые
Пример правильной работы программы:
Исходный массив : 1 2 3 4 0 5
Ответ: 2
Вот что то наваял)
Апгрейт))) нет вроде ошибок если найдёте плз отпишите
попробуйте забагать если получится напишите какие числа пробовали
И отпишите как улучшить программу если у кого есть какие-нибудь соображения
И если у кого будет интерес просмотреть код МОЖНО ЛИ СДЕЛАТЬ ТАМ ГДЕ У МЕНЯ САМАЯ ОСНОВНАЯ ЧАСТЬ ЧТО БЫ ОБОЙТИСЬ БЕЗ РЕГИСТРОВ
data segment
req db 10,13,'ENTER ARRAY:$'
error db "INCORRECT NUMBER$"
inpbuf db 30
len db 0
DBbuF db 30 dup (?)
dwArray dw 60 dup (?)
dimension dw 0
FIND dw 0
msg1 db 10,13,"THE SECOND LARGEST EVEN NUMBER:$"
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
;================================================================
;==========================input array===========================
;================================================================
XOR CX, CX
XOR BX, BX
mov ah, 09h
lea dx, req
int 21h
mov ah, 0Ah
lea dx, inpbuf
int 21h
LEA SI, DBbuF
LEA DI, dwArray
MOV BX, 10 ;notation
XOR DX, DX
nachalo:
PUSH DX
cmp byte ptr [si],"-"
jnz positive
mov BP,1
inc si
positive:
xor ax,ax
cycle:
mov CL,[SI]
CMP CL,0dh ;ne konec li stroki
JZ proverka
CMP CL,20h
JZ proverka ; konec chisla (probel)
CMP CL,'0'
JL er
CMP CL,'9'
JA er
SUB CL,'0'
MUL BX
ADD AX, CX
INC SI
JMP cycle
proverka:
POP DX
INC DX
CMP BP,1
JNZ neminys
NEG AX
neminys:
XOR BP, BP
MOV [DI], AX
ADD DI, 2
INC SI
CMP CL, 0dh
JZ endin
JMP nachalo
er:
MOV DX, offset error
MOV AH, 09
INT 21h
endin:
MOV dimension, DX
;================================================================
;==========================main part=============================
;================================================================
LEA SI, dwArray
MOV CX, dimension
XOR DX, DX
PUSH CX
PUSH SI
Max1LooP:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX ;Parity
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE Skip1 ;if <>
MOV BP, AX ;MAX -> BP
INC DX ;the even number
Skip1:
CMP DX, 0 ;the even number (at least one)
LOOPE Max1LooP
JE EXIT ;no even numbers
;-----------------------------------------------------------------
POP SI
POP CX
PUSH CX
PUSH SI
MaxLooP:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX ;Parity
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE ODD ;if <>
CMP AX, BP ;AX[SI] - BP[MAX]
JL LessEven ;IF AX<BX -> lesseven (AX<max)
MOV BP, AX ;BP <- max[AX]
JMP ODD
LessEven:
MOV DX, AX ;
ODD:
LOOP MaxLooP
;-------------------------------------------------------------------
POP SI
POP CX
PUSH SI
PUSH CX
SecondMaxLooP:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX ;Parity
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE OddNumber ;if <>
CMP AX, BP
JE OddNumber
MOV DX, AX ;MAX = AX
OddNumber:
LOOP SecondMaxLooP
POP CX
POP SI
SecondMaxLooP2:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX ;Parity
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE OddNumber1 ;if <>
CMP AX, BP
JE OddNumber1
CMP AX, DX
JL oddNumber1
MOV DX, AX
OddNumber1:
LOOP SecondMaxLooP2
MOV FIND, DX
;================================================================
;==========================display a message on the screen=======
;================================================================
LEA DX, msg1
MOV AH, 9
INT 21h
;================================================================
;==========================Result output=========================
;================================================================
MOV AX, FIND
TEST AX, AX
JNS oi1
MOV CX, AX
MOV AH, 02H
MOV DL, '-'
INT 21H
MOV AX, CX
NEG AX
oi1:
XOR CX, CX
MOV BX, 10
oi2:
XOR DX, DX
DIV BX
PUSH DX
INC CX
TEST AX,AX
JNZ oi2
MOV AH, 02H
oi3:
POP DX
CMP DL, 9
JBE oi4
ADD DL, 7
oi4:
ADD DL, '0'
INT 21H
LOOP oi3
EXIT:
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start; multi-segment executable file template.
data segment
req db 10,13,'ENTER ARRAY:$'
error db 10,13,"INPUT ERROR$"
pkey db 10,13,"press any key...$"
msg1 db 10,13,"THE SECOND LARGEST EVEN NUMBER:$"
inpbuf db 50
len db 0
DBbuF db 50 dup (?)
dwArray dw 100 dup (?)
dimension dw 0
FIND dw 0
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
;================================================================
;==========================input array===========================
;================================================================
XOR CX, CX
XOR BX, BX
InputStart:
mov ah, 09h
lea dx, req
int 21h
mov ah, 0Ah
lea dx, inpbuf
int 21h
CMP len, 0
JE er
LEA SI, DBbuF
LEA DI, dwArray
MOV BX, 10 ;notation
XOR DX, DX
nachalo:
PUSH DX
cmp byte ptr [si],"-"
jnz positive
mov BP,1
inc si
positive:
xor ax,ax
cycle:
mov CL,[SI]
CMP CL,0dh ;ne konec li stroki
JZ proverka
CMP CL,20h
JZ proverka ; konec chisla (probel)
CMP CL,'0'
JL er
CMP CL,'9'
JA er
SUB CL,'0'
MUL BX
ADD AX, CX
INC SI
JMP cycle
proverka:
POP DX
INC DX
CMP BP,1
JNZ neminys
NEG AX
neminys:
XOR BP, BP
MOV [DI], AX
ADD DI, 2
INC SI
CMP CL, 0dh
JZ endin
JMP nachalo
er:
MOV DX, offset error
MOV AH, 09
INT 21h
;======================
;=wait for any key....=
;======================
lea dx, pkey
mov ah, 9
int 21h
;=====================
;=====================
mov ah, 1
int 21h
;======================
;=====clear screen=====
;======================
MOV AH, 00H
MOV AL, 03H
INT 10H
JMP InputStart
endin:
MOV dimension, DX
;================================================================
;==========================main part=============================
;================================================================
LEA SI, dwArray
MOV CX, dimension
XOR DX, DX
PUSH CX
PUSH SI
checkARRAY:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE wrong ;if <>
MOV BP, AX
INC DL ;the even number
wrong:
CMP DL, 2h ;the even number (at least one)
LOOPNE checkARRAY ;esli 2 nechetnix
JC er ;if CF=1 -->menshe dvyh nechetnix
DEC DL ;est yzhe odno chetnoe chislo
POP SI
POP CX
PUSH CX
PUSH SI
checkARRAY1:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE wrong1 ;if <>
CMP BP, AX
JE wrong1
INC DL ;the even number
wrong1:
CMP DL, 2h ;the even number (at least one)
LOOPNE checkARRAY1 ;esli 2 nechetnix
JC er ;if CF=1 -->menshe dvyh nechetnix
POP SI
POP CX
PUSH CX
PUSH SI
Max1LooP:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX ;Parity
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE Skip1 ;if <>
MOV BP, AX ;MAX -> BP
INC DX ;the even number
Skip1:
CMP DX, 0 ;the even number (at least one)
LOOPE Max1LooP
JE er ;no even numbers
;-----------------------------------------------------------------
POP SI
POP CX
PUSH CX
PUSH SI
MaxLooP:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX ;Parity
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE ODD ;if <>
CMP AX, BP ;AX[SI] - BP[MAX]
JL ODD ;IF AX<BP -> lesseven (AX<max)
MOV BP, AX ;BP <- max[AX]
ODD:
LOOP MaxLooP
;-------------------------------------------------------------------
POP SI
POP CX
PUSH SI
PUSH CX
SecondMaxLooP:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX ;Parity
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE OddNumber ;if <>
CMP AX, BP
JE OddNumber
MOV DX, AX ;MAX = AX
OddNumber:
LOOP SecondMaxLooP
POP CX
POP SI
SecondMaxLooP2:
LODSW ;AX = DS:[SI], SI = SI + 2
MOV BX, AX ;Parity
AND BX, 01h ;Parity
CMP BX, 0 ;Parity
JNE OddNumber1 ;if <>
CMP AX, BP ;AX-[SI] BP-max1
JE OddNumber1 ;if = then exit
CMP AX, DX ;AX-[SI] DX-max2
JL oddNumber1 ;if max>AX then exit
MOV DX, AX ;max=AX
OddNumber1:
LOOP SecondMaxLooP2
MOV FIND, DX ;ANSWER
;================================================================
;==========================display a message on the screen=======
;================================================================
LEA DX, msg1
MOV AH, 9
INT 21h
;================================================================
;==========================Result output=========================
;================================================================
MOV AX, FIND
TEST AX, AX
JNS oi1
MOV CX, AX
MOV AH, 02H
MOV DL, '-'
INT 21H
MOV AX, CX
NEG AX
oi1:
XOR CX, CX
MOV BX, 10
oi2:
XOR DX, DX
DIV BX
PUSH DX
INC CX
TEST AX,AX
JNZ oi2
MOV AH, 02H
oi3:
POP DX
CMP DL, 9
JBE oi4
ADD DL, 7
oi4:
ADD DL, '0'
INT 21H
LOOP oi3
;======================
;=wait for any key....=
;======================
lea dx, pkey
mov ah, 9
int 21h
;=====================
;=====================
mov ah, 1
int 21h
EXIT:
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.BP
ибо говорят что BP используют только для стекаРешение задачи: «Найти второе по величине четное число в линейном массиве»
textual
Листинг программы
Флаг1 = ЛОЖЬ
Флаг2 = ЛОЖЬ
Цикл:
ЧИСЛО = очередной_элемент_массива
Если ЧИСЛО нечетно, то GOTO Конец_цикла
Если Флаг 1 = ЛОЖЬ, то
НАИБОЛЬШЕЕ = ЧИСЛО
Флаг_1 = ПРАВДА
GOTO Конец_цикла
Если ЧИСЛО = НАИБОЛЬШЕЕ, то GOTO Конец_цикла <- вставить
Если Флаг 2 = ЛОЖЬ, то
Если ЧИСЛО <= НАИБОЛЬШЕЕ
ИСКОМОЕ = ЧИСЛО
в противном случае
ИСКОМОЕ = НАИБОЛЬШЕЕ
НАИБОЛЬШЕЕ = ЧИСЛО
Флаг_2 = ПРАВДА
GOTO Конец_цикла
Если ЧИСЛО > НАИБОЛЬШЕЕ
ИСКОМОЕ = НАИБОЛЬШЕЕ
НАИБОЛЬШЕЕ = ЧИСЛО
GOTO Конец_цикла
Если ЧИСЛО > ИСКОМОЕ
ИСКОМОЕ = ЧИСЛО
Конец_цикла:
LOOP Цикл
Если Флаг_2 = ЛОЖЬ, то GOTO на ошибку
Печатаем ИСКОМОЕ
Объяснение кода листинга программы
- Переменная
Флаг1инициализируется значениемЛОЖЬ. - Переменная
Флаг2инициализируется значениемЛОЖЬ. - Цикл начинается.
- Переменная
ЧИСЛОпринимает значение очередного элемента массива. - Если
ЧИСЛОнечетное, то происходит переход кКонец_цикла. - Если
Флаг1равенЛОЖЬ, то:- Переменная
НАИБОЛЬШЕЕпринимает значениеЧИСЛО. - Переменная
Флаг1принимает значениеПРАВДА. - Происходит переход к
Конец_цикла.
- Переменная
- Если
ЧИСЛОравноНАИБОЛЬШЕЕ, то происходит переход кКонец_цикла. - Если
Флаг2равенЛОЖЬ, то:- Если
ЧИСЛОменьше или равноНАИБОЛЬШЕЕ, то:- Переменная
ИСКОМОЕпринимает значениеЧИСЛО.
- Переменная
- В противном случае:
- Переменная
ИСКОМОЕпринимает значениеНАИБОЛЬШЕЕ. - Переменная
НАИБОЛЬШЕЕпринимает значениеЧИСЛО.
- Переменная
- Переменная
Флаг2принимает значениеПРАВДА. - Происходит переход к
Конец_цикла.
- Если
- Если
ЧИСЛОбольшеНАИБОЛЬШЕЕ, то:- Переменная
ИСКОМОЕпринимает значениеНАИБОЛЬШЕЕ. - Переменная
НАИБОЛЬШЕЕпринимает значениеЧИСЛО. - Происходит переход к
Конец_цикла.
- Переменная
- Если
ЧИСЛОбольшеИСКОМОЕ, то:- Переменная
ИСКОМОепринимает значениеЧИСЛО.
- Переменная
- Переменная
Флаг2проверяется на значениеЛОЖЬ. - Если
Флаг2равенЛОЖЬ, то происходит переход к ошибке. - Печатается значение переменной
ИСКОМОЕ.