Числовые данные обычно представлены в двоичной системе. Арифметические инструкции работают с двоичными данными. Когда числа отображаются на экране или вводятся с клавиатуры, они имеют форму ASCII.
До сих пор мы преобразовывали эти входные данные в форме ASCII в двоичный файл для арифметических вычислений и преобразовывали результат обратно в двоичный файл. Следующий код показывает это —
section .text global _start ;must be declared for using gcc _start: ;tell linker entry point mov eax,'3' sub eax, '0' mov ebx, '4' sub ebx, '0' add eax, ebx add eax, '0' mov [sum], eax mov ecx,msg mov edx, len mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov ecx,sum mov edx, 1 mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data msg db "The sum is:", 0xA,0xD len equ $ - msg segment .bss sum resb 1
Когда приведенный выше код компилируется и выполняется, он дает следующий результат —
The sum is: 7
Такие преобразования, однако, имеют накладные расходы, и программирование на ассемблере позволяет более эффективно обрабатывать числа в двоичной форме. Десятичные числа могут быть представлены в двух формах —
- ASCII форма
- BCD или двоично-десятичная форма
ASCII Представительство
В представлении ASCII десятичные числа хранятся в виде строки символов ASCII. Например, десятичное значение 1234 сохраняется как —
31 32 33 34H
Где 31H — значение ASCII для 1, 32H — значение ASCII для 2 и т. Д. Есть четыре инструкции для обработки чисел в представлении ASCII —
-
AAA — ASCII настроить после добавления
-
AAS — ASCII отрегулировать после вычитания
-
AAM — ASCII настроить после умножения
-
AAD — ASCII настроить перед делением
AAA — ASCII настроить после добавления
AAS — ASCII отрегулировать после вычитания
AAM — ASCII настроить после умножения
AAD — ASCII настроить перед делением
Эти инструкции не принимают никаких операндов и предполагают, что требуемый операнд находится в регистре AL.
В следующем примере инструкция AAS используется для демонстрации концепции:
section .text global _start ;must be declared for using gcc _start: ;tell linker entry point sub ah, ah mov al, '9' sub al, '3' aas or al, 30h mov [res], ax mov edx,len ;message length mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov edx,1 ;message length mov ecx,res ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data msg db 'The Result is:',0xa len equ $ - msg section .bss res resb 1
Когда приведенный выше код компилируется и выполняется, он дает следующий результат —
The Result is: 6
BCD Представительство
Существует два типа представления BCD —
- Распакованное BCD представление
- Упакованное представление BCD
В неупакованном представлении BCD каждый байт хранит двоичный эквивалент десятичной цифры. Например, число 1234 хранится как —
01 02 03 04H
Есть две инструкции для обработки этих чисел —
-
AAM — ASCII настроить после умножения
-
AAD — ASCII настроить перед делением
AAM — ASCII настроить после умножения
AAD — ASCII настроить перед делением
Четыре инструкции настройки ASCII, AAA, AAS, AAM и AAD, также могут использоваться с неупакованным представлением BCD. В упакованном представлении BCD каждая цифра сохраняется с использованием четырех битов. Две десятичные цифры упакованы в байт. Например, число 1234 хранится как —
12 34H
Есть две инструкции для обработки этих чисел —
-
DAA — десятичная корректировка после добавления
-
DAS — десятичное значение после вычитания
DAA — десятичная корректировка после добавления
DAS — десятичное значение после вычитания
В упакованном представлении BCD отсутствует поддержка умножения и деления.
пример
Следующая программа складывает два 5-значных десятичных числа и отображает сумму. Он использует вышеуказанные понятия —
section .text global _start ;must be declared for using gcc _start: ;tell linker entry point mov esi, 4 ;pointing to the rightmost digit mov ecx, 5 ;num of digits clc add_loop: mov al, [num1 + esi] adc al, [num2 + esi] aaa pushf or al, 30h popf mov [sum + esi], al dec esi loop add_loop mov edx,len ;message length mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov edx,5 ;message length mov ecx,sum ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data msg db 'The Sum is:',0xa len equ $ - msg num1 db '12345' num2 db '23456' sum db ' '
Когда приведенный выше код компилируется и выполняется, он дает следующий результат —