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)   
|