- FasmWorld - https://fasmworld.ru -

Учебный курс. Часть 12. Преобразование типов

Очень часто в программах приходится выполнять действия с числами разного размера, например складывать или умножать байт и слово. Напрямую процессор не умеет выполнять такие операции, поэтому в этом случае необходимо выполнять преобразование типов. Сложность представляет преобразование меньших типов в большие (байта в слово, слова в двойное слово и т.д.)

Преобразовать больший тип в меньший гораздо проще — достаточно отбросить старшую часть. Но такое преобразование небезопасно и может привести к ошибке. Например, если значение слова без знака больше 255, то сделав из него байт, вы получите некорректное значение. Будьте внимательны, если вы используете такие трюки в своей программе.

Преобразование типов без знака

Преобразование типов выполняется по-разному для чисел со знаком и без. Для преобразования чисел без знака необходимо просто заполнить все старшие биты нулями. Например, так будет выглядеть преобразование байта в слово:

Такое преобразование можно выполнить с помощью обычной команды MOV [1] (x объявлен как байт):

    mov bl,[x]
    mov bh,0     ;BX = x
;Или вот так:
    mov bl,[x]
    sub bh,bh    ;BX = x 

Но кроме того в системе команд процессора существует специальная команда — MOVZX [1] (копирование с нулевым расширением). Первый операнд команды имеет размер 16 бит (слово), а второй — 8 бит (байт). Тот же результат можно получить так:

    movzx bx,[x] ;BX = x

Преобразование типов со знаком

Для чисел со знаком всё немного сложнее. Если мы просто заполним старшую часть нулями, то результат будет положительным, а это не всегда верно. Поэтому преобразование выполняется путём копирования знакового бита на всю старшую часть. То есть для положительного числа со знаком старшая часть будет заполняться нулями, а для отрицательного — единицами:

Для такого преобразования предназначена команда MOVSX [2] (копирование со знаковым расширением). Первый операнд — слово, второй операнд — байт. Например (y объявлен как байт):

    movsx cx,[y] ;CX = y

Существуют ещё две команды для преобразования типов со знаком: CBW [3] (Convert Byte to Word — преобразовать байт в слово) и CWD [4] (Convert Word to Double word — преобразовать слово в двойное слово). У этих команд нет явных операндов. Команда CBW [3] преобразует байт, находящийся в регистре AL, в слово в регистре AX. Команда CWD [4] преобразует слово, находящееся в регистре AX, в двойное слово в регистрах DX:AX. Эти команды удобно использовать вместе с командами умножения и деления. Например:

    mov al,[y]
    cbw          ;AX = y
    cwd          ;DX:AX = y

Пример программы

Допустим, требуется вычислить значение формулы x = (a + b) / c. Все числа со знаком. Размер x — двойное слово, размер a — байт, размер b и c — слово.

use16                 ;Генерировать 16-битный код
org 100h              ;Программа начинается с адреса 100h

    movsx ax,[a]      ;AX = a
    add ax,[b]        ;AX = a+b
    cwd               ;DX:AX = a+b
    idiv [c]          ;AX = (a+b)/c, в DX остаток
    cwd               ;DX:AX = (a+b)/c
    mov word[x],ax    ;\
    mov word[x+2],dx  ;/ x = DX:AX

    mov ax,4C00h      ;\
    int 21h           ;/ Завершение программы
;-------------------------------------------------------
a   db -55
b   dw -3145
c   dw 100
x   dd ?                 

Упражнение

Напишите программу для вычисления формулы z = (x·y) / (x + y). Все числа со знаком. Размер x — байт, размер y — слово, размер z — двойное слово. Проверьте работу программы в отладчике. Результаты можете выкладывать в комментариях.

Следующая часть » [5]