Вычислите значение кусочной функции - 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).

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.429 из 5
Похожие ответы