Вычислите значение кусочной функции - Assembler/FASM
Формулировка задачи:
F(x) =
x, если x < 0 x/2, если 0 <= x <= 3 x-5, если x > 3 Программа работает, но в диапазоне от 0 до 3 нужно вывести результат деления. Помогите вывести в результате число с остатком.use16
org 100h
mov ax, [x]
CMP ax , 0
JL @Ext ; x < 0
CMP ax, 3
JG @m2 ; x > 3
CMP ax, 3
JLE @m1 ; x <= 3
CMP ax, 0
JGE @m1 ; x >= 0
@m1:
mov bl, 2
div bl
jmp @Ext
@m2:
sub ax, 5
jmp @Ext
@Ext:
mov [ f ] , ax
mov ax, [ f ] ;Число, которое будем выводить
mov cx,print_str ;Адрес процедуры print_str
mov bx,print_endline ;Адрес процедуры print_endline
mov di,x1_x
call cx ;Вывод строки 'signed byte :'
call bx ;Вывод конца строки
mov di,x2_x
call cx ;Вывод строки 'signed byte :'
call bx ;Вывод конца строки
mov di,x3_x
call cx ;Вывод строки 'signed byte :'
call bx ;Вывод конца строки
mov di,x_x
call cx ;Вывод строки 'signed byte :'
call print_byte_sdec ;Вывод AL в десятичном виде (со знаком)
call bx ;Вывод конца строки
mov ax, [ x ] ;Число, которое будем выводить
mov cx,print_str ;Адрес процедуры print_str
mov bx,print_endline ;Адрес процедуры print_endline
mov di,s_sbyte
call cx ;Вывод строки 'signed byte :'
call print_byte_sdec ;Вывод AL в десятичном виде (со знаком)
call bx ;Вывод конца строки
mov di,s_pak
call cx ;Вывод строки 'Press any key...'
mov ah,8 ;Функция DOS 08h - ввод символа без эха
int 21h
mov ax,4C00h ;\
int 21h ;/ Завершение программы
;----------------------------------------------------------------------
;Процедура вывода байта на консоль в десятичном виде (без знака)
; AL - байт
print_byte_udec:
push di
mov di,buffer ;DI = адрес буфера
push di ;Сохранение DI в стеке
call byte_to_udec_str ;Преобразование байта в AL в строку
mov byte[di],'$' ;Добавление символа конца строки
pop di ;DI = адрес начала строки
call print_str ;Вывод строки на консоль
pop di
ret
;----------------------------------------------------------------------
;Процедура вывода слова на консоль в десятичном виде (без знака)
; AX - слово
print_word_udec:
push di
mov di,buffer ;DI = адрес буфера
push di ;Сохранение DI в стеке
call word_to_udec_str ;Преобразование слова в AX в строку
mov byte[di],'$' ;Добавление символа конца строки
pop di ;DI = адрес начала строки
call print_str ;Вывод строки на консоль
pop di
ret
;----------------------------------------------------------------------
;Процедура вывода байта на консоль в десятичном виде (со знаком)
; AL - байт
print_byte_sdec:
push di
mov di,buffer ;DI = адрес буфера
push di ;Сохранение DI в стеке
call byte_to_sdec_str ;Преобразование байта в AL в строку
mov byte[di],'$' ;Добавление символа конца строки
pop di ;DI = адрес начала строки
call print_str ;Вывод строки на консоль
pop di
ret
;----------------------------------------------------------------------
;Процедура вывода слова на консоль в десятичном виде (со знаком)
; AX - слово
print_word_sdec:
push di
mov di,buffer ;DI = адрес буфера
push di ;Сохранение DI в стеке
call word_to_sdec_str ;Преобразование слова в AX в строку
mov byte[di],'$' ;Добавление символа конца строки
pop di ;DI = адрес начала строки
call print_str ;Вывод строки на консоль
pop di
ret
;----------------------------------------------------------------------
;Процедура вывода строки на консоль
; DI - адрес строки
print_str:
push ax
mov ah,9 ;Функция DOS 09h - вывод строки
xchg dx,di ;Обмен значениями DX и DI
int 21h ;Обращение к функции DOS
xchg dx,di ;Обмен значениями DX и DI
pop ax
ret
;----------------------------------------------------------------------
;Процедура вывода конца строки (CR+LF)
print_endline:
push di
mov di,endline ;DI = адрес строки с символами CR,LF
call print_str ;Вывод строки на консоль
pop di
ret
;----------------------------------------------------------------------
;Процедура преобразования байта в строку в десятичном виде (без знака)
; AL - байт.
; DI - буфер для строки (3 символа). Значение регистра не сохраняется.
byte_to_udec_str:
push ax
xor ah,ah ;Преобразование байта в слово (без знака)
call word_to_udec_str ;Вызов процедуры для слова без знака
pop ax
ret
;----------------------------------------------------------------------
;Процедура преобразования слова в строку в десятичном виде (без знака)
; AX - слово
; DI - буфер для строки (5 символов). Значение регистра не сохраняется.
word_to_udec_str:
push ax
push cx
push dx
push bx
xor cx,cx ;Обнуление CX
mov bx,10 ;В BX делитель (10 для десятичной системы)
wtuds_lp1: ;Цикл получения остатков от деления
xor dx,dx ;Обнуление старшей части двойного слова
div bx ;Деление AX=(DX:AX)/BX, остаток в DX
add dl,'0' ;Преобразование остатка в код символа
push dx ;Сохранение в стеке
inc cx ;Увеличение счетчика символов
test ax,ax ;Проверка AX
jnz wtuds_lp1 ;Переход к началу цикла, если частное не 0.
wtuds_lp2: ;Цикл извлечения символов из стека
pop dx ;Восстановление символа из стека
mov [di],dl ;Сохранение символа в буфере
inc di ;Инкремент адреса буфера
loop wtuds_lp2 ;Команда цикла
pop bx
pop dx
pop cx
pop ax
ret
;----------------------------------------------------------------------
;Процедура преобразования байта в строку в десятичном виде (со знаком)
; AL - байт.
; DI - буфер для строки (4 символа). Значение регистра не сохраняется.
byte_to_sdec_str:
push ax
movsx ax,al ;Преобразование байта в слово (со знаком)
call word_to_sdec_str ;Вызов процедуры для слова со знаком
pop ax
ret
;----------------------------------------------------------------------
;Процедура преобразования слова в строку в десятичном виде (со знаком)
; AX - слово
; DI - буфер для строки (6 символов). Значение регистра не сохраняется.
word_to_sdec_str:
push ax
test ax,ax ;Проверка знака AX
jns wtsds_no_sign ;Если >= 0, преобразуем как беззнаковое
mov byte[di],'-' ;Добавление знака в начало строки
inc di ;Инкремент DI
neg ax ;Изменение знака значения AX
wtsds_no_sign:
call word_to_udec_str ;Преобразование беззнакового значения
pop ax
ret
;---------------------------------------------------------------------
; Данные
x_x db 13,10,'result= $'
s_uword db 'unsigned word: $'
s_sbyte db 'x= $'
x1_x db 13,10,' |x; x<0$'
x2_x db 'F(x)= |x/2; 0<=x<=3$'
x3_x db ' |x-5; x>3$'
s_sword db 'signed word : $'
s_pak db 13,10,'Press any key...$'
endline db 13,10,'$'
buffer rb 7
x dw 3
f dw ?Решение задачи: «Вычислите значение кусочной функции»
textual
Листинг программы
use16 org 100h ;деление, целая часть mov al, [x] cbw mov bl, [y] idiv bl call ShowInt or ah, ah jz .exit ;если остаток есть - вывести десятичную точку ;и продолжить деление mov al, ah mov si, ax mov ah, 02h mov dl, '.' int 21h mov bh, 10 mov cx, [Len] mov ax, si .digit: mul bh div bl add al, '0' mov dl, al mov al, ah mov si, ax mov ah, 02h int 21h mov ax, si or al, al loopnz .digit .exit: mov ah, 09h mov dx, msgPressAnyKey int 21h mov ah, 10h ;Задержка int 16h ;до нажатия клавиши int 20h ;Завершение программы ShowInt: push ax push bx mov bl, 10 or al, al jns .positive neg al mov ah, 02h mov dl, '-' int 21h .positive: xor cx, cx .siDiv: mov ah, 0 div bl mov dl, ah push dx inc cx or al, al jnz .siDiv mov ah, 02h .show: pop dx add dl, '0' int 21h loop .show pop bx pop ax ret ;--------------------------------------------------------------- ; Данные msgPressAnyKey db 13, 10, 'Press any key to exit...', '$' x db 123 y db 17 Len dw 4 ;количество знаков после запятой
Объяснение кода листинга программы
В данном коде на языке Assembler выполняется деление двух чисел с остатком и выводится десятичная точка в случае, если остаток есть. Затем происходит задержка до нажатия клавиши, после чего программа завершается.
При выполнении кода на экран выводятся сообщения Press any key to exit... и 17 / 123 = 0,1404.
Переменные:
x - 123 (в формате double word);
y - 17 (в формате double word);
Len - 4 (в формате word).