Autor: | Wojciech Muła |
---|---|
Dodany: | 2002 |
CPU potrafi przeprowadzać operacje arytmetyczne tylko na rejestrach o tych samych rozmiarach. Dlatego też operacje na operandach o różnych rozmiarach trzeba poprzedzić poszerzeniem zakresu operandu o mniejszej liczbie bitów.
Rozszerzenie zakresu polega na zapisaniu tej samej wartości w słowie o większej liczbie bitów. Dla liczb bez znaku, zapisanych w naturalnym kodzie binarnym, jest to bardzo proste — wystarczy nowe, „dodane” bity wyzerować.
Np. 8-bitowa liczba 166=10100110b po rozszerzeniu na 32 bity ma postać:
00000000 00000000 00000000 10100110
Dla liczb ze znakiem jest to trochę trudniejsze — nowe bity należy wypełnić bitem znaku.
Np. 8-bitowa liczba -100 = 10011100b po rozszerzeniu na 32 bity ma postać:
11111111 11111111 11111111 10100110
Poniższe sposoby można stosować dla dowolnych rejestrów.
extend_x86.asm:
; al -> ax xor ah, ah ; wyzeruj ah and ax, 0x00ff ; j.w. movzx ax, al ; al -> eax and eax, 0x000000ff movzx eax, al
extend_mmx.asm:
; packed byte -> packed word ; mm0 -> mm1:mm0 ; mm0 = 0x10ff200faabbccdd pxor mm2, mm2 ; mm2 = 0x0000000000000000 movq mm1, mm0 ; mm1 = 0x0000000000000000 punpcklbw mm0, mm2 ; mm0 = 0x00aa00bb00cc00dd punpckhbw mm1, mm2 ; mm1 = 0x001000ff0020000f
Lub inaczej:
extend_mmx.asm:
; packed byte -> packed word ; mm0 -> mm1:mm0 movq mm1, mm0 punpcklbw mm0, mm0 punpckhbw mm1, mm1 psrlw mm0, 8 psrlw mm1, 8
Poniższe rozkazy działają tylko dla akumulatora (al, ax, eax).
extend_stdx86:
cbw ; al -> ax cwd ; ax -> eax cwde ; eax -> edx:eax
A te już dla dowolnych rejestrów i pamięci.
extend_u2.asm:
; al -> ax mov ah, al sar ah, al ; al -> eax ; eax = |xxxxxxxx|xxxxxxxx|xxxxxxxx|shhhllll| shr eax, 24 ; eax = |shhhllll|00000000|00000000|00000000| sar eax, 24 ; eax = |ssssssss|ssssssss|ssssssss|shhhllll| ; eax -> edx:eax mov edx, eax sar edx, eax ; lub troszkę dłuższy kod xor edx, edx cmp eax, 0 setge dl sub edx, 1
extend_u2mmx.asm:
; packed signed byte -> packed signed word ; mm0 -> mm1:mm0 movq mm1, mm0 punpcklbw mm0, mm0 punpcklbw mm1, mm1 psraw mm0, 8 psraw mm1, 8