home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.asm.x86      Ahh, the lost art of x86 assembly      4,675 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 4,339 of 4,675   
   Terje Mathisen to John   
   Re: ITOA in 65 bytes   
   15 May 21 19:46:21   
   
   From: terje.mathisen@nospicedham.tmsw.no   
      
   Kerr-Mudd, John wrote:   
   > On Sat, 15 May 2021 11:21:43 +0100   
   > "Kerr-Mudd, John"  wrote:   
   >   
   >> On Fri, 14 May 2021 21:53:32 +0200   
   >> Terje Mathisen  wrote:   
   >>   
   >>> Robert Prins wrote:   
   >>>> Is it possible to fit the conversion of a 16 bit signed integer to   
   >>>> left-aligned ASCII without leading zeroes in just 65 bytes?   
   >>>   
   >>> Naively I would say yes: I assume you don't care about speed here?   
   >>>   
   >>> ;; AX has the value to be converted to ascii   
   >> [code elided]   
   >> I took the liberty of moving the "mov bx,10" out of the loop!   
   >   
   > How embarrassing; needs bx setting if +ve!   
   >   
   >> NASM .lst file:   
   >>   
   >       1                                  org 0x100   
   >       2                                  cpu 8086   
   >       3   
   >       4                                  ;; AX has the value to be converted   
   to ascii   
   >       5                                  ;; Store the string to the buffer   
   pointed to by DI   
   >       6 00000000 B8FF7F                         mov ax,0x7FFF   
   >       7 00000003 BF[2F00]                       mov di,Ostr   
   >       8   
   >       9                                  putnum:   
   >      10 00000006 31C9                       xor cx,cx	; Count how many   
   digits we find   
   >      11 00000008 85C0                       test ax,ax	; Positive?   
   >      12 0000000A 7D06                        jge notneg   
   >      13   
   >      14                                  ;; Negative input value, so print a   
   '-' sign   
   >      15 0000000C C6052D                     mov byte [di],'-'   
   >      16 0000000F F7D8                       neg ax   
   >      17 00000011 47                         inc di   
   >      18                                  notneg:   
   >      19 00000012 BB0A00                     mov bx,10   
   >      20   
   >      21                                  next:   
   >      22                                  ;   xor dx,dx   
   >      23 00000015 99                         cwd          ; ok as hibit has   
   been removed   
   >      24 00000016 F7F3                       div bx   
   >      25 00000018 52                         push dx	; Remainder is the digit   
   >      26 00000019 41                         inc cx   
   >      27 0000001A 85C0                       test ax,ax	; Is it zero yet?   
   >      28 0000001C 75F7                        jnz next   
   >      29   
   >      30                                  dump_digits:   
   >      31 0000001E 58                         pop ax   
   >      32 0000001F 0430                       add al,'0'   
   >      33 00000021 AA                         stosb   
   >      34 00000022 E2FA                        loop dump_digits   
   >      35   
   >      36                                  convlth equ $-putnum   
   >      37   
   >      38 00000024 B82409                      mov ax,0x100*9+'$'   
   >      39 00000027 AA                          stosb   
   >      40 00000028 BA[2F00]                    mov dx,Ostr   
   >      41 0000002B CD21                        int 0x21   
   >      42 0000002D C3                          ret   
   >      43 0000002E 1E                      db convlth   
   >      44                                     Ostr equ $   
   >   
   >>   
   >>> That looks like 17 instructions, most of them two-byte, 5 one-byte and a   
   >>> couple that are longer, so 32-35 bytes?   
   >>   
   >> 1E=30 bytes   
      
   The CWD was a valid improvement, moving BX=10 out of the loop probably   
   doesn't matter that much since the DIV BX takes forever. :-(   
      
   The key idea here is of course that I abuse the stack as temporary   
   storage to reverse the digits to be printed, since the challenge was to   
   get below 65 bytes I think my code was pretty good for a simple   
   "programming while responding to clax post" exercise. :-)   
      
   I did consider printing each digit directly to the console, it probably   
   would not have added much to the code size for an unsigned value, but   
   getting the sign logic correct was much easier when using the STOSB buffer.   
      
      xor cx,cx   
      test ax,ax   
       jge not_negative   
      
      xchg ax,bx   
      mov dl,'-' - '0'   
      call print_char   
      xchg ax,bx   
      neg ax   
      
   not_negative:   
      mov bx,10   
   next:   
   ...   
      test ax,ax   
       jnz next   
      
   print_digits:   
      pop dx   
      call print_char   
       loop print_digits   
      ret   
      
   print_char:   
      add dl,'0'   
      mov ah,2   
      int 21h   
      ret   
      
      
   Terje   
      
      
   --   
   -    
   "almost all programming can be viewed as an exercise in caching"   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca