logo
Pract / Prakt4

Додавання в ascii-форматі

Розглянемо процес додавання чисел 8 і 4 в ASCII-форматі: 38h+34h=6Ch. Отримана сума неправильна ні для ASCII-формату, ні для двійкового формату. Однак, ігноруючи ліву 6 і додавши 6 до правої .Ch: Ch + 6 =12h - одержимо правильний результат у десятковому форматі. Цей приклад злегка спрощено, але він добре демонструє процес, що виконує команда AAA при корекції.

Для прикладу, припустимо, що регістр AX містить 0038h, а регістр BX - 0034h. Числа 38 і 34 представляють два байти в ASCII форматі, які необхідно додати. Додавання й корекція кодується наступними командами:

ADD AL,BL ;Додати 34 і 38

AAA ;Корекція для додавання ASCII кодів.

Команда AAA перевіряє праву шістнадцяткову. цифру (4 біти) у регістрі AL. Якщо ця цифра знаходиться між Ah і Fh або прапорець AF дорівнює 1, то до регістра AL додається 6, а до регістра AH додається 1, прапорці AF і CF встановлюються в 1. У всіх випадках команда AAA встановлює в 0 ліву шіст. цифру в регістрі AL. Результат - у регістрі AX:

Після команди ADD: 006C

Після команди AAA: 0102

Для того, щоб отримати остаточне ASCII-значення, досить просто поставити трійки на місце лівих шістнадцяткових цифр:

OR AX,3030H ;Результат 3132

Все показане вище представляє додавання однобайтовых чисел. Додавання багатобайтних ASCII-чисел вимагає організації циклу, що виконує обробку справа наліво із врахуванням переносу. Приклад , показаний нижче, додає два трибайтні ASCII-числа в чотирибайтну суму.

.

TITLE ASCADD (COM) Додавання в ASCII-форматі

ASSUME CS:CODESG,DS:CODESG,SS:CODESG

ORG 100H

BEGIN: JMP SHORT MAIN

ASC1 DB '578' ; Елементи даних

ASC2 DB '694'

ASC3 DB '0000'

MAIN PROC NEAR

CLC

LEA SI,AASC1+2 ; Адреса ASCII-чисел

LEA DI,AASC2+2

LEA BX,AASC1+3

MOV CX,03 ; Виконати 3 цикли

A20:

MOV AH,00 ; Очистити регістр AH

MOV AL,[SI] ; Загрузить ASCII-байт

ADC AL,[DI] ; Додавання (з переносом)

AAA ; Корекція для ASCII

MOV [BX],AL ; Збереження суми

DEC SI

DEC DI

DEC BX

LOOP A20 ; Виконати 3 цикли

MOV [BX],AH ; Зберегти перенос

RET

MAIN ENDP

CODESG ENDS

END BEGIN

Зверніть увагу на наступне:

В результаті виходить сума у вигляді 01020702. Програма не використає команду OR після команди AAA для занесення лівої трійки, тому що при цьому встановлюється прапорець CF, що змінить результат команди ADC. Одним з рішень у цьому випадку є збереження регістра прапорців за допомогою команди PUSHF, виконання команди OR, і, потім, відновлення регістра прапорців командою POPF:

ADC AL,[DI] ;Додавання з переносом

AAA ;Корекція для ASCII

PUSHF ;Збереження прапорців

OR AL,30H ;Запис лівої трійки

POPF ;Відновлення прапорців

MOV [BX],AL ;Збереження суми

Замість команд PUSHF і POPF можна використати команди LAHF (Load AH with Flags - завантаження прапорців у регістр AH) і SAHF (Store AH in Flag register - запис прапорців з регістра AH у регістр прапорців). Команда LAHF завантажує в регістр AH прапорці SF, ZF, AF, PF і CF; а команда SAHF записує вміст регістра AH у зазначені прапорці. У наведеному прикладі, однак, регістр AH уже використовується для арифметичних переповнень. Інший спосіб вставки трійок для одержання ASCII-кодів цифр - організувати обробку суми командою OR у циклі.