- •Лабораторная работа №3
- •А. Постановка задачи
- •Б. Разработка алгоритма
- •Если число введено неверно, то вывод: "incorrect. " — и возврат к п. 4.
- •Конвертирование числа из ascii формата в bin.
- •Вызов функции 2-ой лабораторной работы.
- •Вывод результата.
- •Выход из программы. В. Таблица идентификаторов
- •Г. Таблица результатов
- •Е. Программа
- •; Файл nasm
- •Ж. Выводы
Г. Таблица результатов
Результаты вычислений приведены ниже в таблице вычислений.
Тип |
A |
B |
X |
Signed Word |
10000 |
20000 |
TASM: 2504 NASM: 2504 |
1500 |
3000 |
TASM: 379 NASM: 379 |
|
6000 |
7000 |
TASM: 879 NASM: 879 |
|
7000 |
6000 |
TASM: 0 NASM: 0 |
|
-10000 |
-10000 |
TASM: 2 NASM: 2 |
|
32760 |
32765 |
TASM: 4099 NASM: 4099 |
|
32765 |
32760 |
TASM: 0 NASM: 0 |
|
65535 |
65533 |
TASM: 1 NASM: 1 |
Д. Makefile (Linux x64)
all: main
main: main.o
gcc -no-pie main.o
main.o: main.asm
nasm -f elf64 $^
clean:
rm -rf *.o *.bin
Е. Программа
/* TASM */
;-----------------CODE-----------------
CODESG SEGMENT PARA 'CODE'
BEGIN PROC FAR
ASSUME CS: CODESG, SS: STACKSG, DS: DATASG, ES: DATASG
PUSH DS
SUB AX, AX
PUSH AX
MOV AX, DATASG
MOV DS, AX
MOV ES, AX
JMP NORMAL1 ; Идем к вводу
MESSAGE_ERROR_LABEL1: ; В первый раз обходим эту метку
CALL COUT_ENDL
MOV AH, 09
LEA DX, INPUT_ERROR_MESSAGE
INT 21H
NORMAL1:
MOV AH, 09
LEA DX, MESSAGE1
INT 21H ; Выводим приглашение к вводу числа A
MOV AH, 0AH
LEA DX, IPARAM
INT 21H ; Вводим число A
LEA SI, FIELD – 1 ; Настраиваем
MOV BH, 0
MOV BL, ASCLEN
CALL IS_NUMBER ; Проверяем, число ли это
JNZ MESSAGE_ERROR_LABEL1 ; Если нет, то идем к метке ошибки и повторяем
CALL ASCII_TO_BIN ; Конверт в BIN
MOV AX, BIN_VALUE
MOV NUMBER1, AX
CALL COUT_ENDL ; Добавляем перевод строки
JMP NORMAL2 ; Идем к вводу
MESSAGE_ERROR_LABEL2: ; В первый раз обходим эту метку
MOV AH, 09
LEA DX, INPUT_ERROR_MESSAGE
INT 21H
NORMAL2:
MOV AH, 09
LEA DX, MESSAGE2
INT 21H ; Выводим приглашение к вводу
MOV BIN_VALUE, 0 ; Обнуляем
MOV MULT10, 1 ; К начальному состоянию
MOV AH, 0AH
LEA DX, IPARAM
INT 21H ; Вводим число B
CALL COUT_ENDL ; Добавляем перевод строки
LEA SI, FIELD – 1 ; Настраиваем
MOV BH, 0
MOV BL, ASCLEN
CALL IS_NUMBER ; Проверяем, число ли это
JNZ MESSAGE_ERROR_LABEL2 ; Если нет, то идем к метке ошибки и повторяем
CALL ASCII_TO_BIN ; Конверт в BIN
MOV AX, BIN_VALUE
MOV NUMBER2, AX
CALL LABSI ; Вызываем функцию 2-ой лабораторной работы
CALL BIN_TO_ASCII ; Конверт в ASCII
MOV AH, 09H
LEA DX, RESULT
INT 21H ; Выводим результат
MOV AX, 4C00H
INT 21H ; Завершаем работу программы
RET
BEGIN ENDP
LABSI PROC NEAR ; Функция второй лабораторной
PUSH AX
PUSH BX
PUSH DX
MOV AX, NUMBER1
CMP AX, NUMBER2
JG SI_BIGSMALL
JL SI_SMALLBIG
JE SI_EQUAL
SI_BIGSMALL:
MOV AX, NUMBER2
MOV BX, NUMBER1
ADD AX, 2
CWD ; <DX:AX>
IDIV BX
MOV BIN_VALUE, AX
JMP SI_BRANCH
SI_SMALLBIG:
MOV AX, NUMBER2
MOV BX, 8
CWD ; <DX:AX>
IDIV BX
ADD AX, 4
MOV BIN_VALUE, AX
JMP SI_BRANCH
SI_EQUAL:
MOV AX, 2
MOV BIN_VALUE, AX
JMP SI_BRANCH
SI_BRANCH:
POP DX
POP BX
POP AX
RET
LABSI ENDP
COUT_ENDL PROC NEAR ; Функция печатающая перевод строки
PUSH AX
PUSH DX
MOV AH, 09
LEA DX, ENDLINE
INT 21H
POP DX
POP AX
RET
COUT_ENDL ENDP
ASCII_TO_BIN PROC NEAR ; Функция конверта из ASCII в BIN
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV CX, 10
MOV DX, BX ; SAVE LEN TO DX
MOV BX, 1
MOV AL, [SI + BX]
MOV BX, DX
XOR DX, DX
MOV DI, BX ; DI = BX
CMP AL, '-' ; AL IS MINUS?
JNE B20 ; NO
DEC DI ; YES
B20:
MOV AL, [SI + BX]
AND AX, 000FH
MUL MULT10
ADD BIN_VALUE, AX
MOV AX, MULT10
MUL CX
MOV MULT10, AX
DEC BX
DEC DI
JNZ B20
CMP BX, DI ; IF BX == DI
JE END_B ; NO MINUS
; ELSE MINUS:
MOV AX, BIN_VALUE
NEG AX
MOV BIN_VALUE, AX
END_B:
POP DI
POP DX
POP CX
POP BX
POP AX
RET
ASCII_TO_BIN ENDP
IS_NUMBER PROC NEAR ; Функция проверки ASCII-числа
PUSH AX
PUSH BX
PUSH CX
MOV CX, BX ; SAVE LEN IN CX
MOV BX, 1 ; BX = 1
MOV AL, [SI + BX] ; AL = (CHAR)
CMP AL, '-' ; AL IS MINUS?
MOV BX, CX ; LEN IN BX
; NO - JUMP
JNE IS_NUM
; YES:
DEC CX
IS_NUM:
MOV AL, [SI + BX]
CMP AL, '0'
JB ERROR_N
CMP AL, '9'
JA ERROR_N
DEC BX
DEC CX
JNZ IS_NUM
JMP BRANCHI
ERROR_N:
STC
BRANCHI:
POP CX
POP BX
POP AX
RET
IS_NUMBER ENDP
BIN_TO_ASCII PROC NEAR ; Функция конверта из BIN в ASCII
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
MOV CX, 0010
LEA SI, RESULT + 5
MOV AX, BIN_VALUE
MOV BX, AX
AND BX, 8000H
CMP BX, 8000H
JB C20
MOV BX, AX
MOV AX, 65535
SUB AX, BX
ADD AX, 1
MOV BX, 1
C20:
CMP AX, 0010
JB C30
XOR DX, DX
DIV CX
OR DL, 30H
MOV [SI], DL
DEC SI
JMP C20
C30:
OR AL, 30H
MOV [SI], AL
CMP BX, 1
JE ADDMINUS
JMP RETFUNC
ADDMINUS:
DEC SI
MOV AL, ZMINUS
MOV [SI], AL
RETFUNC:
POP SI
POP DX
POP CX
POP BX
POP AX
RET
BIN_TO_ASCII ENDP
CODESG ENDS
;---------------END CODE---------------
;-----------------STACK-----------------
STACKSG SEGMENT PARA STACK 'STACK'
DW 32 DUP(?)
STACKSG ENDS
;---------------END STACK---------------
;-----------------DATA-----------------
DATASG SEGMENT PARA 'DATA'
INPUT_ERROR_MESSAGE DB 'INCORRECT. $'
MESSAGE1 DB 'ENTER A: $'
MESSAGE2 DB 'ENTER B: $'
NUMBER1 DW ?
NUMBER2 DW ?
IPARAM LABEL BYTE
MAXLEN DB 20
ASCLEN DB ?
FIELD DB 20 DUP (' ')
MULT10 DW 1
BIN_VALUE DW 0
ENDLINE DB 13, 10, '$'
ZMINUS DB '-$'
RESULT DB ' $'
DATASG ENDS
;---------------END DATA---------------
END BEGIN