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 2,905 of 4,675   
   Robert Prins to All   
   Converting some way to clever PL/I code    
   03 Aug 17 23:00:16   
   
   From: robert@nospicedham.prino.org   
      
   I've recently come across some really clever/very nasty PL/I code, that would,   
   theoretically, save CPU by eliminating a conditional jump. It relies on   
   initializing a BCD-encoded ***integer*** variable ("sum") with -0.1, which   
   results, on IBM mainframes, the last nibble of the BCD encoded value to contain   
   0xD (rather than the normal 0xC). The author uses this to avoid a costly   
   (Phuleeze, pass me a bucket!) test, so rather than coding:   
      
   sum = -1;   
      
   do i = 1 to whatever;   
      if a(i) >= 0 then   
        if sum <> -1 then   
          sum = sum + a(i);   
        else   
          sum = a(i);   
   end;   
      
   if sum <> -1 then "print sum";   
      
   the code can be simplified to   
      
   sum = -0.1; /* fraction is discarded, but -sign (0xD) is kept! */   
      
   do i = 1 to whatever;   
      if a(i) >= 0 then   
        sum = sum + a(i);   
   end;   
      
   if last_nibble(sum) <> 0xD then "print sum";   
      
   where "last_nibble" is a simplification of using two actual PL/I builtin   
   functions that actually allow access to the last nibble of a BCD encoded value,   
   and the addition of any a(i) to "sum", even an a(i) = 0 will cause the CPU to   
   normalize the last nibble of "sum" to 0xC.   
      
   Testing this for big "whatever" (in an outer loop, and using a small array "a"   
   in the inner loop) makes no flipping difference (on a Hercules emulated) z/OS   
   system, which doesn't surprise yours truly one Iota. :)   
      
   However, I would be curious if there is a way to code something similar in x86   
   assembler, when using strictly integer values, which  implies that sum/eax must   
   be initialized to -1(?), and the addition is preceded by a "cmp eax, -1(?)" to   
   set up a carry, but that doesn't seem to work.   
      
   Or am I just on a wild goose chase?   
      
   Obviously using a "cmp eax, -1" followed by a "sete dl / movzx edx,dl / add   
   eax,edx / add eax, 'a(i)'" works, but might take a few nano-seconds more than a   
   pretty much very well predicted conditional jump...   
      
   Any thoughts?   
      
   Robert   
   --   
   Robert AH Prins   
   robert(a)prino(d)org   
      
   --- 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