TITLE "CONVERT" - Převádí čísla do různých soustav ... .8086 ; Linkuje se pro i8086 PAGE 67, 130 ; Stránka 67 zn., délka 130 zn./řádek COMMENT @ =========================================================================== Název souboru : CONVERT.ASM Link OBJ & LIB : CONVERT.ZIP Datum úprav : 01.09.97 Verze programu : 4.00 (c) Copyright : 1993,94,95,96,97 by NST 32 , Medo Zdeněk junior ===========================================================================@ Knihovna_NST32 SEGMENT PARA PUBLIC 'CODE' USE16 ASSUME CS:Knihovna_NST32 PUBLIC __c_bcd_b_ascii ; EXTRN __c_bcd_b_ascii :PROC :NEAR PUBLIC __c_bcd_w_ascii ; EXTRN __c_bcd_w_ascii :PROC :NEAR PUBLIC __c_byte_ascii ; EXTRN __c_byte_ascii :PROC :NEAR PUBLIC __c_word_ascii ; EXTRN __c_word_ascii :PROC :NEAR PUBLIC __c_dword_ascii ; EXTRN __c_dword_ascii :PROC :NEAR ; 386 PUBLIC __c_byte_ascii_hex ; EXTRN __c_byte_ascii_hex :PROC :NEAR PUBLIC __c_dword_ascii_hex ; EXTRN __c_dword_ascii_hex :PROC :NEAR ; 386 PUBLIC __c_word_ascii_hex ; EXTRN __c_word_ascii_hex :PROC :NEAR PUBLIC __c_byte_ascii_bin ; EXTRN __c_byte_ascii_bin :PROC :NEAR PUBLIC __c_word_ascii_bin ; EXTRN __c_word_ascii_bin :PROC :NEAR PUBLIC __c_ascii_hex_word ; EXTRN __c_ascii_hex_word :PROC :NEAR PUBLIC __c_ascii_hex_byte ; EXTRN __c_ascii_hex_byte :PROC :NEAR PUBLIC __c_ascii_byte ; EXTRN __c_ascii_byte :PROC :NEAR PUBLIC __c_ascii_word ; EXTRN __c_ascii_word :PROC :NEAR PUBLIC __c_del_zero_dec ; EXTRN __c_del_zero_dec :PROC :NEAR PUBLIC __c_add_zero_dec ; EXTRN __c_add_zero_dec :PROC :NEAR ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo BCD byte na ASCII ; -------------- ; ; Volání(např.) : mov al, BCD BYTE ; BCD BYTE číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_bcd_b_ascii ; Convert BCD byte to ASCII ; ; Výstup : DS:SI = převedeno na 2 znaky ASCII ; -------------- AX = převedeny 2 znaky na ASCII ; ; Mění registry : Flags, AX ; -------------- ; ;--------------------------------------------------------------------------- __c_bcd_b_ascii PROC NEAR push cx ; Ulož reg. mov cl, 4 ; Bude se 4x rotovat mov ah, al ; AH = Nižší 4 bity shr al, cl ; AL = Vyšší 4 bity and ax, 0F0Fh add ax, '00' ; Konvertuj do ASCII pop cx ; Obnov reg. mov word ptr ds:[si], ax ; Ulož ASCII znak do řetězce retn ; Návrat NEAR __c_bcd_b_ascii ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo BCD WORD na ASCII. ; -------------- Používá pro převod funkci __c_bcd_b_ascii. ; ; Volání(např.) : mov ax, BCD WORD ; BCD WORD číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_bcd_w_ascii ; Convert BCD word to ASCII ; ; Výstup : DS:SI = převedeno na 4 znaky ASCII ; -------------- AX = převedeny poslední 2 znaky na ASCII ; ; Mění registry : Flags, AX ; -------------- ; ;--------------------------------------------------------------------------- __c_bcd_w_ascii PROC NEAR push si ax ; Ulož reg. xchg al, ah ; Prohoď reg. call __c_bcd_b_ascii ; Převeď 1 část BCD add si, 2 ; Pozice v tislu pop ax ; Převeď AL xchg ah, al ; Prohoď reg. call __c_bcd_b_ascii ; Převeď 2 část BCD pop si ; Obnov reg. retn ; Návrat NEAR __c_bcd_w_ascii ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo BYTE na ASCII. ; -------------- ; ; Volání(např.) : mov al, BYTE ; BYTE číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_byte_ascii ; Convert BYTE to ASCII ; ; Výstup : DS:SI = převedeno na 3 znaky ASCII ; -------------- ; ; Mění registry : Flags ; -------------- ; ;--------------------------------------------------------------------------- __c_byte_ascii PROC NEAR push cx si ax ; Ulož reg. mov cl, 100 ; Počítej stovky call Převeď_AL mov cl, 10 ; Počítej desítky call Převeď_AL call AL_ASCII ; Počítej jednotky pop ax si cx ; Obnov reg. retn ; Návrat NEAR Převeď_AL: xor ah, ah div cl ; AL = AX / CL (výsledek) ; AH = AX mod BL (zbytek) AL_ASCII: add al, '0' ; AL = AL + '0' (korekce na ASCII) mov byte ptr ds:[si], al ; Ulož výsledek do řetězce inc si mov al, ah ; Zbytek po dělení do AL retn ; Návrat NEAR __c_byte_ascii ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo WORD na ASCII. ; -------------- ; ; Volání(např.) : mov ax, WORD ; WORD číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_word_ascii ; Convert WORD to ASCII ; ; Výstup : DS:SI = převedeno na 5 znaků ASCII ; -------------- ; ; Mění registry : Flags ; -------------- ; ;--------------------------------------------------------------------------- __c_word_ascii PROC NEAR push ax cx dx si ; Ulož reg. mov cx, 10000 ; Počítej desetitisíce call Převeď_AX mov cx, 1000 ; Počítej tisíce call Převeď_AX mov cx, 100 ; Počítej stovky call Převeď_AX mov cx, 10 ; Počítej desítky call Převeď_AX call AX_ASCII ; Počítej jednotky pop si dx cx ax ; Obnov reg. retn ; Návrat NEAR Převeď_AX: xor dx, dx div cx ; AX = DX&AX / CX (výsledek) ; DX = DX&AX mod CX (zbytek) AX_ASCII: add al, '0' ; AL = AL + '0' (korekce na ASCII) mov byte ptr ds:[si], al ; Ulož výsledek do řetězce inc si mov ax, dx ; Zbytek po dělení do AX retn ; Návrat NEAR __c_word_ascii ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo DWORD na ASCII. ; -------------- Funkce jde použít pouze na procesorech 80 386 a vyšších !!! ; ; Volání(např.) : mov eax, DWORD ; DWORD číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_dword_ascii ; Convert DWORD to ASCII {jen 386} ; ; Výstup : DS:SI = převedeno na 10 znaků ASCII ; -------------- ; ; Mění registry : Flags ; -------------- ; ;--------------------------------------------------------------------------- .386 ; Linkuje se pro i80386 __c_dword_ascii PROC NEAR push eax ecx edx si ;Ulož reg. mov ecx, 1000000000 call Převeď_EAX mov ecx, 100000000 call Převeď_EAX mov ecx, 10000000 call Převeď_EAX mov ecx, 1000000 call Převeď_EAX mov ecx, 100000 call Převeď_EAX mov ecx, 10000 call Převeď_EAX mov ecx, 1000 call Převeď_EAX mov ecx, 100 call Převeď_EAX mov ecx, 10 call Převeď_EAX call EAX_ASCII ; Počítej jednotky pop si edx ecx eax ; Obnov reg. retn ; Návrat NEAR Převeď_EAX: xor edx, edx div ecx ; EAX = EDX&EAX / ECX (výsledek) ; EDX = EDX&EAX mod ECX (zbytek) EAX_ASCII: add al, '0' ; AL = AL + '0' (korekce na ASCII) mov byte ptr ds:[si], al ; Ulož výsledek do řetězce inc si mov eax, edx ; Zbytek po dělení do EAX retn ; Návrat NEAR __c_dword_ascii ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo BYTE na HEX ASCII ; -------------- ; ; Volání(např.) : mov al, BYTE ; BYTE číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_byte_ascii_hex ; Convert BYTE to HEX ASCII ; ; Výstup : DS:SI = převedeno na 2 znaky ASCII ; -------------- ; ; Mění registry : Flags ; -------------- ; ;--------------------------------------------------------------------------- .8086 ; Linkuje se pro i8086 __c_byte_ascii_hex PROC NEAR push si cx ax ax ; Ulož reg. mov cl, 4 shr al, cl ; 4x rotuj do prava call ASCII_AL_HEX ; Převeď AL na ASCII - vyšší bit. pop ax and al, 0Fh ; nižšší bit. call ASCII_AL_HEX ; Použij podprogram z WORD_HEX_ASCII pop ax cx si ; Obnov reg. retn ; Návrat NEAR __c_byte_ascii_hex ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo WORD na HEX ASCII ; -------------- ; ; Volání(např.) : mov ax, WORD ; WORD číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_word_ascii_hex ; Convert WORD to HEX ASCII ; ; Výstup : DS:SI = převedeno na 4 znaky ASCII ; -------------- ; ; Mění registry : Flags ; -------------- ; ;--------------------------------------------------------------------------- __c_word_ascii_hex PROC NEAR push ax cx si ; Ulož reg. xchg al, ah ; Prohoď reg. call Převeď_AL_HEX ; Počítej xchg al, ah ; Prohoď reg. call Převeď_AL_HEX ; Počítej pop si cx ax ; Obnov reg. retn ; Návrat NEAR Převeď_AL_HEX: push ax mov cl, 4 shr al, cl ; 4x rotuj do prava call ASCII_AL_HEX ; Převeď AL na ASCII - vyšší bit. pop ax and al, 0Fh ; Nižší bit. ASCII_AL_HEX: add al, '0' ; Přičti cmp al, '0'+10 ; Je v AL znak ASCII ? jb HEX_ASCII_ZNAK ; Ano, skoč add al, 'A'-'0'-10 ; Ne, přičti ... HEX_ASCII_ZNAK: mov byte ptr ds:[si], al ; Ulož HEX znak do řetězce inc si retn ; Návrat NEAR __c_word_ascii_hex ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo DWORD na HEX ASCII ; -------------- Funkce jde použít pouze na procesorech 80 386 a vyšších !!! ; ; Volání(např.) : mov eax, DWORD ; DWORD číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_dword_ascii_hex ; Convert WORD to HEX ASCII {jen 386} ; ; Výstup : DS:SI = převedeno na 8 znaků ASCII ; -------------- ; ; Mění registry : Flags ; -------------- ; ;--------------------------------------------------------------------------- .386 ; Linkuje se pro i80386 __c_dword_ascii_hex PROC NEAR push eax cx si ; Ulož reg. rol eax, 16 ; Otoč EAX xchg al, ah ; Prohoď reg. call Převeď_AL_HEX ; Počítej xchg al, ah ; Prohoď reg. call Převeď_AL_HEX ; Počítej rol eax, 16 ; Vrať zpět EAX xchg al, ah ; Prohoď reg. call Převeď_AL_HEX ; Počítej xchg al, ah ; Prohoď reg. call Převeď_AL_HEX pop si cx eax ; Obnov reg. retn ; Návrat NEAR __c_dword_ascii_hex ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo BYTE na BIN ASCII ; -------------- ; ; Volání(např.) : mov al, BYTE ; BYTE číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_byte_ascii_bin ; Convert BYTE to BIN ASCII ; ; Výstup : DS:SI = převedeno na 8 znaků ASCII ; -------------- ; ; Mění registry : Flags, AX ; -------------- ; ;--------------------------------------------------------------------------- .8086 ; Linkuje se pro i8086 __c_byte_ascii_bin PROC NEAR push cx si ; Ulož reg. mov cx, 8 ; 8-bitů ROTUJ_AL: shl al, 1 ; Rotuj do leva jc AL_CF_1 ; Je-li v CF 1 skoč ... mov byte ptr ds:[si], '0' ; Ulož ASCII znak do řetězce jmp BBA_END AL_CF_1: mov byte ptr ds:[si], '1' ; Ulož ASCII znak do řetězce BBA_END: inc si loop ROTUJ_AL pop si cx ; Obnov pomocný reg. retn ; Návrat NEAR __c_byte_ascii_bin ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď číslo WORD na BIN ASCII ; -------------- ; ; Volání(např.) : mov ax, WORD ; WORD číslo pro převedení ; -------------- mov si, OFFSET TXT ; DS:SI řetězec pro přeložené číslo ; call __c_word_ascii_bin ; Convert WORD to BIN ASCII ; ; Výstup : DS:SI = převedeno na 16 znaků ASCII ; -------------- ; ; Mění registry : Flags, AX ; -------------- ; ;--------------------------------------------------------------------------- __c_word_ascii_bin PROC NEAR push cx si ; Ulož pomocný reg. mov cx, 16 ; 16-bitů ROTUJ_AX: shl ax, 1 ; Rotuj do leva jc AX_CF_1 ; Je-li v CF 1 skoč ... mov byte ptr ds:[si], '0' ; Ulož ASCII znak do řetězce jmp WBA_END AX_CF_1: mov byte ptr ds:[si], '1' ; Ulož ASCII znak do řetězce WBA_END: inc si loop ROTUJ_AX pop si cx ; Obnov pomocný reg. retn ; Návrat NEAR __c_word_ascii_bin ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď HEX ASCII na číslo BYTE ; -------------- ; ; Volání(např.) : mov si, OFFSET TXT ; DS:SI řetězec pro převod ; -------------- call __c_ascii_hex_byte ; Convert HEX ASCII to BYTE ; ; Výstup : mov al, BYTE ; BYTE číslo po pčevedení z HEX ASCII ; -------------- ; ; Mění registry : Flags, AX ; -------------- ; ;--------------------------------------------------------------------------- __c_ascii_hex_byte PROC NEAR push cx dx si ; Ulož reg. xor dx, dx ; Pomocný reg. mov cl, 4 ; Rotace 4x lodsb ; Načti HEX znak z řetězce (?0H) call AL_HEX_ASCII lodsb ; Načti HEX znak z řetězce (0?H) call AL_HEX_ASCII mov ax, dx ror ax, cl pop si dx cx ; Obnov reg. xor ah, ah ; AH = 0000 retn ; Návrat NEAR AL_HEX_ASCII: sub al, '0' ; Odečti ASCII cmp al, 10 ; Je v AL číslo 0-9 ? jb ASCII_ZNAK ; Ano, skoč sub al, 'A'-'0'-10 ; Ne, odečti ... ASCII_ZNAK: add dl, al rol dx, cl retn ; Návrat NEAR __c_ascii_hex_byte ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď HEX ASCII na číslo WORD ; -------------- ; ; Volání(např.) : mov si, OFFSET TXT ; DS:SI řetězec pro převod ; -------------- call __c_ascii_hex_byte ; Convert HEX ASCII to WORD ; ; Výstup : mov ax, WORD ; WORD číslo po převedení z HEX ASCII ; -------------- ; ; Mění registry : Flags, AX ; -------------- ; ;--------------------------------------------------------------------------- __c_ascii_hex_word PROC NEAR push cx dx si ; Ulož reg. xor dx, dx ; Pomocný reg. mov cl, 4 ; Rotace 4x lodsb ; Načti HEX znak z řetězce (?000H) call AL_HEX_ASCII lodsb ; Načti HEX znak z řetězce (0?00H) call AL_HEX_ASCII lodsb ; Načti HEX znak z řetězce (00?0H) call AL_HEX_ASCII lodsb ; Načti HEX znak z řetězce (000?H) call AL_HEX_ASCII mov ax, dx ror ax, cl pop si dx cx ; Obnov reg. retn ; Návrat NEAR __c_ascii_hex_word ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď 3 ASCII na číslo BYTE ; -------------- ; ; Volání(např.) : mov si, OFFSET TXT ; DS:SI řetězec pro převod ; -------------- call __c_ascii_byte ; Convert ASCII to BYTE ; ; Výstup : mov al, BYTE ; BYTE číslo po převedení z ASCII ; -------------- ; ; Mění registry : Flags, AX ; -------------- ; ;--------------------------------------------------------------------------- __c_ascii_byte PROC NEAR push dx cx si ; Ulož reg. xor dx, dx ; DX = 0000 call Načti_BYTE ; Načti ASCII a konvertuj jej do AL mov cl, 100 ; Počítej stovky call ASCII_AL call Načti_BYTE ; Načti ASCII a konvertuj jej do AL mov cl, 10 ; Počítej stovky call ASCII_AL call Načti_BYTE ; Načti ASCII a konvertuj jej do AL mov cl, 1 ; Počítej stovky call ASCII_AL mov al, dl xor ah, ah ; AH = 00 pop si cx dx ; Obnov reg. retn ; Návrat NEAR ASCII_AL: xor ah, ah mul cl ; AL = AX * CL (výsledek) ; AH = AX mod CL (zbytek) add dl, al retn ; Návrat NEAR Načti_BYTE: mov al, byte ptr [si] ; Načti ASCII znak cmp al, ' ' ; Je to Mezera ? jne Ne_Mez ; Ne, skoč ... mov al, '0' ; Doplň mezeru nulou Ne_Mez: inc si ; Další znak ... sub al, '0' ; AL = AL - '0' (korekce z ASCII na BYTE) retn ; Návrat NEAR __c_ascii_byte ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : Převeď 5 ASCII na číslo WORD ; -------------- ; ; Volání(např.) : mov si, OFFSET TXT ; DS:SI řetězec pro převod ; -------------- call __c_ascii_word ; Convert ASCII to WORD ; ; Výstup : mov ax, WORD ; WORD číslo po převedení z ASCII ; -------------- ; ; Mění registry : Flags, AX ; -------------- ; ;--------------------------------------------------------------------------- __c_ascii_word PROC NEAR push bx cx dx si ; Ulož reg. xor bx, bx ; BX = 0000 call Načti_WORD ; Načti ASCII a konvertuj jej do AL mov cx, 10000 ; Počítej deseti-tisíce call ASCII_AX call Načti_WORD ; Načti ASCII a konvertuj jej do AL mov cx, 1000 ; Počítej tisíce call ASCII_AX call Načti_WORD ; Načti ASCII a konvertuj jej do AL mov cx, 100 ; Počítej stovky call ASCII_AX call Načti_WORD ; Načti ASCII a konvertuj jej do AL mov cx, 10 ; Počítej stovky call ASCII_AX call Načti_WORD ; Načti ASCII a konvertuj jej do AL mov cx, 1 ; Počítej stovky call ASCII_AX mov ax, bx ; AX = BX pop si dx cx bx ; Obnov reg. retn ; Návrat NEAR ASCII_AX: xor ah, ah mul cx ; AL = AX * CL (výsledek) ; AH = AX mod CL (zbytek) add bx, ax ; Přičti k BX retn ; Návrat NEAR Načti_WORD: mov al, byte ptr [si] ; Načti ASCII znak cmp al, ' ' ; Je to Mezera ? jne Ne_MezX ; Ne, skoč ... mov al, '0' ; Doplň mezeru nulou Ne_MezX: inc si ; Další znak ... sub al, '0' ; AL = AL - '0' (korekce z ASCII na BYTE) retn ; Návrat NEAR __c_ascii_word ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : V řetězci DS:SI po převodu odmaže nuly (zleva do prava). ; -------------- (POZOR ! To platí pouze pro DEC. soustavu) ; ; Volání(např.) : mov cx, 2 ; Počet desetiných míst ; -------------- ; BYTE = 2 ; ; WORD = 4 ; ; DWORD = 9 ; mov si, OFFSET TXT ; DS:SI řetězec po převodu ; call __c_del_zero_dec ; Smaž nuly po převodu ; ; Výstup : DS:SI ; Převedený řetězec bez nul ; -------------- ; ; Mění registry : Flags ; -------------- ; ;--------------------------------------------------------------------------- __c_del_zero_dec PROC NEAR push cx si ; Ulož reg. Null_Z: cmp byte ptr [si], '0' ; Je to '0' ? jne No_Zero ; Ne, skoč ... mov byte ptr [si], ' ' ; Vlož mezeru místo nuly inc si ; Další ASCII znak loop Null_Z ; Opkauj smyčku No_Zero: pop si cx ; Obnov reg. retn ; Návrat NEAR __c_del_zero_dec ENDP ;--------------------------------------------------------------------------- ; ; Popis funkce : V řetězci DS:SI před převodem nahradí mezery nulou (zleva do prava). ; -------------- (POZOR ! To platí pouze pro DEC. soustavu) ; ; Volání(např.) : mov cx, 2 ; Počet desetiných míst ; -------------- ; BYTE = 2 ; ; WORD = 4 ; ; DWORD = 9 ; mov si, OFFSET TXT ; DS:SI řetězec po převodu ; call __c_add_zero_dec ; Nahraď mezery nulou ; ; Výstup : DS:SI ; Převedený řetězec bez nul ; -------------- ; ; Mění registry : Flags ; -------------- ; ;--------------------------------------------------------------------------- __c_add_zero_dec PROC NEAR push cx si ; Ulož reg. Null_Z1: cmp byte ptr [si], ' ' ; Je to mezera ? jne No_Zero1 ; Ne, skoč ... mov byte ptr [si], '0' ; Vlož místo mezeru, nulu inc si ; Další ASCII znak loop Null_Z1 ; Opkauj smyčku No_Zero1: pop si cx ; Obnov reg. retn ; Návrat NEAR __c_add_zero_dec ENDP Knihovna_NST32 ENDS END