Programowanie w języku Assembler » FAQ

Jak skonwertować słowo na postać szesnastkową w ASCII

  • 2006-01-17 02:19
  • 3 komentarze
  • 1110 odsłon
  • Oceń ten tekst jako pierwszy
Do napisania mojego pierwszego artykułu skłoniła mnie wskazówka dodana przez Dryobatesa o zamianie wartości ośmiobitowej na jej reprezentację dziesiętną w postaci ciągu znaków. Poniższy fragment robi to samo ze słowem z tym, że wynik jest w postaci szesnastkowej. Pierwsza wersja jest zdecydowanie dłuższa od drugiej, ale być może wykonuje się szybciej. Należało by przetestować. Można by jeszcze zoptymalizować je pod kątem Pentium wyższych rzędów, aby w miarę możliwości instrukcje były wykonywane równolegle, ale to już temat na osobną poradę...

Dane wejściowe:
   ax - liczba do zamiany
Dane wyjściowe:
   wartosc - 4 bajty jako Ascii

wartosc db 4 dup(?)
 
Hex2Ascii Proc   ;wersja dłuższa
   push di
   push ax
   lea di,wartosc+3
   and al,0fh
   call AL2Ascii
   mov [di],al
   dec di
   pop ax
   push ax
 
   shr al,4
   call AL2Ascii
   mov [di],al
   dec di
   pop ax
   push ax
 
   shr ax,8
   and al,0fh
   call AL2Ascii
   mov [di],al
   dec di
   pop ax
   push ax
 
   shr ax,12
   call AL2Ascii
   mov [di],al
   pop ax
   pop di
   ret
Hex2Ascii EndP
 
Hex2Ascii2 Proc   ;wersja krótsza
   push di
   push dx
   push bx
   push ax
   mov dx,ax
   lea bx,wartosc
   mov di,3
@1:
   and al,0fh
   call AL2Ascii
   mov [bx+di],al
   shr dx,4
   mov ax,dx
   dec di
   jns @1
 
   pop ax
   pop bx
   pop dx
   pop di
   ret
Hex2Ascii2 EndP
 
 
AL2Ascii Proc   ;funkcja pomocnicza
   add al,90h
   daa
   adc al,40h
   daa
   ret
AL2Ascii EndP


Funkcja AL2Ascii jest dość powszechnie znanym sposobem na zamianę wartości z zakresu <0;f> na wartość odpowiednio z zakresu <'0'..'9','A'..'F'>.

Dryobates : dzięki za trafne uwagi

3 komentarze

Marooned 2005-04-08 04:10

komentarz... no cóż... może kiedyś ;)

donadam 2004-05-30 03:49

ok, ale przydalby sie komentarz

Mavie 2004-03-23 20:34

Przy pisaniu programu potrzebowałem wyświelić aktualną datę i godzinę (funkcje 04h i 02h przerwania 1ah), a ponieważ dane zwrócone przez te funkcje sa w BCD, więc potrzebowałem je skonwertować na ASCII. To mój pierwszy program w Asemblerze, więc nie udało mi się umiejscowić w nim żadnej procedury zamiany znalezionej na stronach internetowych (łącznie z powyższą). Za to udało mi się stworzyć własną, dużo prostszą i krótszą, nie używającą pamięci, a jedynie rejestrów. Procedura bcd2ascii pobiera kod BCD z AL i wyświetla na ekranie w miejscu wskazanym wcześniej przez kursor, najpierw część młodszą, a potem po jej lewej stronie starszą. Gdyby ktoś sobie życzył inaczej to trzeba pozmieniać kolejność i inkrementować DL.

bcd2ascii proc
  mov ah,al
  ror ah,4
  and ah,00001111b
  and al,00001111b
  mov dh,ah
  add al,30h
  mov ah,0ah
  mov cx,1h
  int 10h
  mov al,dh
  mov ah,03h
  mov bh,0h
  int 10h
  dec dl
  mov ah,02h
  int 10h
  add al,30h
  mov ah,0ah
  mov cx,1h
  int 10h
  ret
bcd2ascii endp