flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
Tomasz Grysztar 04 Dec 2018, 14:01
This is actually a quite useful basic example that perhaps should be publicly available in annotated version as a learning material. And it only took me a couple of minutes to write it, so it is not a big deal to give it to a public domain as an educational sample for anyone that wants (or needs) to learn some basics of 16-bit assembly programming in DOS:
Code: org 100h ; DOS .COM program, loaded at address 100h in a segment pointed to by CS, DS, ES and SS start: mov ax,0x1234 call print_hex_16 int 20h ; exit program print_hex_16: ; in: ax = 16-bit number mov dx,ax ; keep a copy of the number mov bx,hex_table ; DS:BX now points to the table of ASCII characters representing the digits mov di,txt_digits ; ES:DI now points to place in memory where the converted number shall be stored mov cx,4 ; number of digits .convert_digit: mov al,dh ; take the highest nibble shr al,4 ; (nibble is a 4-bit portion, it corresponds to single hexadecimal digit) shl dx,4 ; shift the remaining nibbles one up xlatb ; convert number in AL according to the table at DS:BX stosb ; store digit at ES:DI, increase DI loop .convert_digit ; decrease CX, if still not zero, jump back and repeat the loop mov ah,9 ; DOS function 9, to print the prepared text mov dx,txt_prefix ; DS:DX should point to the complete text to print, ended with '$' character int 21h ; call DOS ret hex_table db '0123456789ABCDEF' txt_prefix db '0x' ; beginning of the produced string txt_digits db '0000' ; reserve digits, immediately after prefix txt_suffix db '$' ; special character recognized by DOS as the end of the string to print |
|||
![]() |
|
sina 05 Dec 2018, 07:12
well, you ask for something and god answers
![]() below is what I could come up with, and yes your's is better, thx. Love&Hate Tomasz ![]() Code: mov ax, 01234h call print_word int 020h ; exit to dos interrupt print_word: push ax; put the value of ax on top of stack shr ax, 8 ; right shift value of ax 8 bits (get leftmost two nibbles) call print_byte pop ax; restore value of ax push ax; put the value of ax on top of stack and ax, 0ffh ; get last 8 bits of ax (get rightmost two nibbles) call print_byte pop ax; restore value of ax ret ; return print_byte: push ax; put the value of ax on top of stack shr al, 4 ; right shift value of al 4 bits(get left nibble) call printchar pop ax; restore value of ax and al, 0fh ; get last 4 bits of al(get right nibble) call printchar ret ; return printchar: add al, 030h ; add hex value 30 to convert to ascii(0=30h, 9=39h) cmp al, 039h ; compare value with ascii code for 9 jle printchar_letter; jump if value is less than or equal(ZF, CF) add al, 07h ; add 7 to convert numbers bigger than 9 to ascii(A=41h) printchar_letter: mov dl, al; move character to write to dl mov ah, 02h ; set int21h mode to write character to stdout int 021h ; execute interrupt ret ; return |
|||
![]() |
|
TightCoderEx 05 Dec 2018, 09:56
Here is another example and you'll probably find there be as many combinations and permutations as there are programmers. I use this quite often, especially for volatile data when once it's done with and because it's on the stack, it disappears.
Building output from the end provides an easy way of padding output. Code: org 0x100 push bp mov bp, sp ; Create a procedure frame mov cx, 4 std ; So index register get automatically decremented mov di, sp dec di sub sp, 16 ; Give ourselves lots of room mov al, '$' stosb ; Set terminating character mov ax, 0x3d0f ; Even if AX = 0, this will print at least one '0' Conv: push ax and ax, 15 ; Strip all but lower 4 bits cmp al, 9 jbe @F add al, 7 ; So AL will be (A-Z) @@: add al, '0' stosb dec cl pop ax shr ax, 4 jnz Conv ; When AX = 0, no point doing anymore conversions or cl, cl ; CX > 0 means with want to padd buffer jz @F mov al, ' ' ; AL can be whatever you want to padd leading spaces with rep stosb @@: cld ; Set auto-increment again mov dx, di inc dx ; Bump ahead to actual first character mov ah, 9 int 0x21 leave ; Restore SP to return to executive ret This is not a competition, but as a matter of curiosity, this code comes in @ 58 bytes sina's 54 Tomasz's 62 |
|||
![]() |
|
sina 05 Dec 2018, 10:11
thanks for the effort
well to be honest, I love the hex table and xlatb approach |
|||
![]() |
|
Tomasz Grysztar 05 Dec 2018, 10:24
Well, if you aimed for reduced size, you could cut out the table (including the BX setup) and replace XLATB with this tricky sequence:
Code: cmp al,10 ; if x < 10, set CF = 1 sbb al,69h ; 0-9: 96h .. 9Fh, A-F: A1h..A6h das ; 0-9: subtr. 66h -> 30h-39h, ; A-F: subtr. 60h -> 41h..46h |
|||
![]() |
|
Mikl___ 05 Dec 2018, 11:00
Last edited by Mikl___ on 08 Dec 2018, 15:25; edited 1 time in total |
|||
![]() |
|
sina 07 Dec 2018, 08:13
If you poke the devil
![]() |
|||
![]() |
|
Mikl___ 07 Dec 2018, 12:33
Hi, sina!
Is it a compliment or sarcasm? ![]() |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.