Montaj - Numaralar
Sayısal veriler genellikle ikili sistemde temsil edilir. Aritmetik komutlar ikili veriler üzerinde çalışır. Numaralar ekranda görüntülendiğinde veya klavyeden girildiğinde ASCII formundadır.
Şimdiye kadar, ASCII formundaki bu girdi verilerini aritmetik hesaplamalar için ikiliye dönüştürdük ve sonucu tekrar ikiliye çevirdik. Aşağıdaki kod bunu göstermektedir -
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
Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki sonucu verir -
The sum is:
7
Bununla birlikte, bu tür dönüşümlerin bir yükü vardır ve montaj dili programlaması, sayıların ikili biçimde daha verimli bir şekilde işlenmesine izin verir. Ondalık sayılar iki biçimde gösterilebilir -
- ASCII formu
- BCD veya İkili Kodlu Ondalık form
ASCII Gösterimi
ASCII gösteriminde, ondalık sayılar ASCII karakter dizileri olarak saklanır. Örneğin, 1234 ondalık değeri -
31 32 33 34H
31H, 1 için ASCII değeridir, 32H, 2 için ASCII değeridir ve bu böyle devam eder. ASCII gösteriminde sayıları işlemek için dört talimat vardır -
AAA - Eklemeden Sonra ASCII Ayarı
AAS - Çıkarmadan Sonra ASCII Ayarı
AAM - Çarpma İşleminden Sonra ASCII Ayarı
AAD - ASCII Bölüm Öncesi Ayarla
Bu talimatlar herhangi bir işlenen almaz ve gerekli işlenin AL yazmacında olduğunu varsayar.
Aşağıdaki örnek, kavramı göstermek için AAS talimatını kullanır -
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
Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki sonucu verir -
The Result is:
6
BCD Temsilciliği
İki tür BCD gösterimi vardır -
- Ambalajsız BCD gösterimi
- Paketlenmiş BCD gösterimi
Paketlenmemiş BCD gösteriminde, her bayt bir ondalık basamağın ikili eşdeğerini depolar. Örneğin, 1234 sayısı -
01 02 03 04H
Bu numaraları işlemek için iki talimat vardır -
AAM - Çarpma İşleminden Sonra ASCII Ayarı
AAD - ASCII Bölüm Öncesi Ayarla
Dört ASCII ayarlama talimatı, AAA, AAS, AAM ve AAD, paketlenmemiş BCD gösterimi ile de kullanılabilir. Paketlenmiş BCD gösteriminde, her rakam dört bit kullanılarak saklanır. İki ondalık hane bir bayta paketlenmiştir. Örneğin, 1234 sayısı -
12 34H
Bu numaraları işlemek için iki talimat vardır -
DAA - Eklemeden Sonra Ondalık Ayar
DAS - Çıkarmadan Sonra Ondalık Ayar
Paketlenmiş BCD gösteriminde çarpma ve bölme desteği yoktur.
Misal
Aşağıdaki program iki adet 5 basamaklı ondalık sayı ekler ve toplamı görüntüler. Yukarıdaki kavramları kullanır -
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 ' '
Yukarıdaki kod derlendiğinde ve yürütüldüğünde, aşağıdaki sonucu verir -
The Sum is:
35801