Annotation of pgp/contrib/idea/idea.asm, revision 1.1

1.1     ! root        1:        %PAGESIZE       59      ; Turbo assembler formatting codes
        !             2:        %BIN    13
        !             3:        %LINUM  3
        !             4: 
        !             5: ; Copyright (c) 1993 Colin Plumb.  This code may be freely
        !             6: ; distributed under the terms of the GNU General Public Licence.
        !             7: 
        !             8:        .model large
        !             9:        .code
        !            10: 
        !            11: ; A core operation in IDEA is multiplication modulo 65537.
        !            12: ; The valid inputs, 1 through 66636 inclusive are represented in
        !            13: ; 16-bit registers modulo 65536.  I.e. a value of 0 means 65536,
        !            14: ; or -1.  Thus, we need to test for that specially.  -x, modulo
        !            15: ; 65537, is 65537-x = 1-x.
        !            16: ; For any other number, represent the product as a*65536+b.  Since
        !            17: ; 65536 = -1 (mod 65537), this is the same number as b-a.  Should
        !            18: ; this result be negautive (generate a borrow), -n mod 65537 = 1-n
        !            19: ; mod 65536.  Or in other words, if you add the borrow bit back on,
        !            20: ; you get the right answer.
        !            21: 
        !            22: ; This is what the assembly code does.  It forms a zero, and adds
        !            23: ; that on with carry.
        !            24: 
        !            25: ; Another useful optimisation takes advantage of the fact that
        !            26: ; a and b are equal only if the answer is congruent to 0 mod 65537.
        !            27: ; Since 65537 is prime, this happens only if one of the inputs is
        !            28: ; congruent to 0 mod 65537.  Since the inputs are all less than 65537,
        !            29: ; this means it must have been zero.
        !            30: 
        !            31: ; The code below tests for a zero result of the subtraction, and if
        !            32: ; one arises, it branches out of line to figure out what happened.
        !            33: 
        !            34: 
        !            35: ; This code implemets the IDEA encryption algorithm.
        !            36: ; It follows in pseudo-C, where the * operator operates
        !            37: ; modulo 65537, as Idea needs.  (If you don't understand,
        !            38: ; learn IDEA better.)
        !            39: 
        !            40: ; IDEA is works on 16-bit units.  If you're processing bytes,
        !            41: ; it's defined to be big-endian, so an Intel machine needs to
        !            42: ; swap the bytes around.
        !            43: 
        !            44: ; void Idea(u_int16 *in, u_int16 *out, u_int16 *key)
        !            45: ; {
        !            46: ;      register u+int16 x0, x1, x2, x3, s1, s2, round;
        !            47: ;
        !            48: ;      x0 = *in++;  x1 = *in++;  x2 = *in++;  x3 = *in;
        !            49: ;
        !            50: ;      for (round = 0; round < 8; round++) {
        !            51: ;              x0 *= *key++;
        !            52: ;              x1 += *key++;
        !            53: ;              x2 += *key++;
        !            54: ;              x3 *= *key++;
        !            55: ;
        !            56: ;              s1  = x1;  s2  = x2;
        !            57: ;              x2 ^= x0;  x1 ^= x3;
        !            58: ;
        !            59: ;              x2 *= *key++;
        !            60: ;              x1 += x2;
        !            61: ;              x1 *= *key++;
        !            62: ;              x2 += x1;
        !            63: ;
        !            64: ;              x0 ^= x1;  x3 ^= x2;
        !            65: ;              x1 ^= s2;  x2 ^= s1;
        !            66: ;      }
        !            67: ;      *out++ = x0 * *key++;
        !            68: ;      *out++ = x2 + *key++;   /* Yes, this is x2, not x1 */
        !            69: ;      *out++ = x1 + *key++;
        !            70: ;      *out   = x3 * *key;
        !            71: ; }
        !            72: 
        !            73: ; ds:si points to key, ax, dx are temps, args in bx, cx, di, bp
        !            74: ; Trashes *all* registers.  direction flag must be clear.
        !            75: ; Leaves es zero.
        !            76: 
        !            77: ; Since there is no spare register to hold the loop count, I make
        !            78: ; clever use of the stack, pushing the start of the loop several
        !            79: ; times and using a ret instruction to do the return.
        !            80: 
        !            81: ; Annoyingly, lods is fastest on 8086's, but other techniques are
        !            82: ; best on 386's.  Well, that's what the manual says, but real
        !            83: ; life is different.  USELODS wins on a 386SX, at least.
        !            84: ; Leave it set for all platforms.
        !            85: 
        !            86: USELODS        equ     1
        !            87: 
        !            88: ; bp must be x0 for some of the code below to work
        !            89: x0     equ     bp
        !            90: x1     equ     bx
        !            91: x2     equ     cx
        !            92: x3     equ     di
        !            93: ; di must be x3 for some of the code below to work
        !            94: 
        !            95: ;; Now, this is rather interesting.  We test for zero arguments
        !            96: ;; after the multiply.  Assuming random inputs, one or both are
        !            97: ;; zero (2^17-1)/2^32, or approximately 1/32786 of the time.
        !            98: ;; Encryption in any feedback mode produces essentially random
        !            99: ;; inputs, so average-case analysis is okay.  While we don't
        !           100: ;; want the out-of-line code to waste time, it is not worth
        !           101: ;; slowing down the in-line case to speed it up.
        !           102: ;;
        !           103: ;; Basically, we start inverting the source x, and if that was 0,
        !           104: ;; we use the inverse of the key instead.
        !           105: 
        !           106: Core1Z:
        !           107:        neg     x0
        !           108:        jnz     Core1Za
        !           109: if USELODS
        !           110:        sub     x0,[si-2]
        !           111: else
        !           112:        sub     x0,[si]
        !           113: endif
        !           114: Core1Za:
        !           115:        inc     x0
        !           116:        jmp     Core1done
        !           117: Core2Z:
        !           118:        neg     x3
        !           119:        jnz     Core2Za
        !           120: if USELODS
        !           121:        sub     x3,[si-2]
        !           122: else
        !           123:        sub     x3,[si+6]
        !           124: endif
        !           125: Core2Za:
        !           126:        inc     x3
        !           127:        jmp     Core2done
        !           128: Core3Z:
        !           129:        neg     x2
        !           130:        jnz     Core3Za
        !           131: if USELODS
        !           132:        sub     x2,[si-2]
        !           133: else
        !           134:        sub     x2,[si+8]
        !           135: endif
        !           136: Core3Za:
        !           137:        inc     x2
        !           138:        jmp     Core3done
        !           139: Core4Z:
        !           140:        neg     x1
        !           141:        jnz     Core4Za
        !           142: if USELODS
        !           143:        sub     x1,[si-2]
        !           144: else
        !           145:        sub     x1,[si+10]
        !           146: endif
        !           147: Core4Za:
        !           148:        inc     x1
        !           149:        jmp     Core4done
        !           150: 
        !           151: ; We need a constant 0 that we can move into a register without affecting
        !           152: ; the carry flag (as the classic xor ax,ax is wont to do), so we use the
        !           153: ; es register for a constant 0 source.  This is okay even in protected
        !           154: ; mode.  (I *told* you this was tricky code!)
        !           155: 
        !           156: ; BTW, since you wanted to know, this is 8 + 78*4 + 16 = 336 instructions.
        !           157: 
        !           158: Core   proc    near
        !           159:        xor     ax,ax
        !           160:        mov     es,ax
        !           161:        mov     ax,OFFSET Finish
        !           162:        push    ax
        !           163:        mov     ax,OFFSET Coreloop
        !           164:        push    ax      ; Loop 3 times, then return
        !           165:        push    ax
        !           166:        push    ax
        !           167: 
        !           168: Coreloop:
        !           169: if USELODS
        !           170:        lodsw
        !           171: else
        !           172:        mov     ax,[si]         ; x0 *= *key++
        !           173: endif
        !           174:        mul     x0
        !           175:        sub     ax,dx
        !           176:        jz      Core1Z
        !           177:        mov     x0,es
        !           178:        adc     x0,ax
        !           179: Core1done:
        !           180: 
        !           181: if USELODS
        !           182:        lodsw
        !           183:        add     x1,ax
        !           184:        lodsw
        !           185:        add     x2,ax
        !           186: else
        !           187:        add     x1,[si+2]       ; x1 += *key++
        !           188:        add     x2,[si+4]       ; x2 += *key++
        !           189: endif
        !           190: 
        !           191: if USELODS
        !           192:        lodsw
        !           193: else
        !           194:        mov     ax,[si+6]       ; x3 += *key++
        !           195: endif
        !           196:        mul     x3
        !           197:        sub     ax,dx
        !           198:        jz      Core2Z
        !           199:        mov     x3,es
        !           200:        adc     x3,ax
        !           201: Core2done:
        !           202: 
        !           203:        push    x1              ; s1 = x1
        !           204:        push    x2              ; s2 = x2
        !           205: 
        !           206:        xor     x1,x3           ; x1 ^= x3
        !           207:        xor     x2,x0           ; x2 ^= x0
        !           208: 
        !           209: if USELODS
        !           210:        lodsw
        !           211: else
        !           212:        mov     ax,[si+8]       ; x2 *= *key++
        !           213: endif
        !           214:        mul     x2
        !           215:        sub     ax,dx
        !           216:        jz      Core3Z
        !           217:        mov     x2,es
        !           218:        adc     x2,ax
        !           219: Core3done:
        !           220: 
        !           221:        add     x1,x2           ; x1 += x2
        !           222: 
        !           223: if USELODS
        !           224:        lodsw
        !           225: else
        !           226:        mov     ax,[si+10]      ; x1 *= *key++
        !           227: endif
        !           228:        mul     x1
        !           229:        sub     ax,dx
        !           230:        jz      Core4Z
        !           231:        mov     x1,es
        !           232:        adc     x1,ax
        !           233: Core4done:
        !           234: 
        !           235:        add     x2,x1           ; x2 += x1
        !           236: 
        !           237:        xor     x0,x1           ; x0 ^= x1
        !           238:        xor     x3,x2           ; x3 ^= x2
        !           239: 
        !           240:        pop     dx
        !           241:        xor     x1,dx           ; x1 ^= s2
        !           242:        pop     dx
        !           243:        xor     x2,dx           ; x2 ^= s1
        !           244: 
        !           245: ; Second unrolling of loop
        !           246: if USELODS
        !           247:        lodsw
        !           248: else
        !           249:        mov     ax,[si+12]      ; x0 *= *key++
        !           250: endif
        !           251:        mul     x0
        !           252:        sub     ax,dx
        !           253:        jz      Core5Z
        !           254:        mov     x0,es
        !           255:        adc     x0,ax
        !           256: Core5done:
        !           257: 
        !           258: if USELODS
        !           259:        lodsw
        !           260:        add     x1,ax
        !           261:        lodsw
        !           262:        add     x2,ax
        !           263: else
        !           264:        add     x1,[si+14]      ; x1 += *key++
        !           265:        add     x2,[si+16]      ; x2 += *key++
        !           266: endif
        !           267: 
        !           268: if USELODS
        !           269:        lodsw
        !           270: else
        !           271:        mov     ax,[si+18]      ; x3 *= *key++
        !           272: endif
        !           273:        mul     x3
        !           274:        sub     ax,dx
        !           275:        jz      Core6Z
        !           276:        mov     x3,es
        !           277:        adc     x3,ax
        !           278: Core6done:
        !           279: 
        !           280:        push    x1              ; s1 = x1
        !           281:        push    x2              ; s2 = x2
        !           282: 
        !           283:        xor     x1,x3           ; x1 ^= x3
        !           284:        xor     x2,x0           ; x2 ^= x0
        !           285: 
        !           286: if USELODS
        !           287:        lodsw
        !           288: else
        !           289:        mov     ax,[si+20]      ; x2 *= *key++
        !           290: endif
        !           291:        mul     x2
        !           292:        sub     ax,dx
        !           293:        jz      Core7Z
        !           294:        mov     x2,es
        !           295:        adc     x2,ax
        !           296: Core7done:
        !           297: 
        !           298:        add     x1,x2           ; x1 += x2
        !           299: 
        !           300: if USELODS
        !           301:        lodsw
        !           302: else
        !           303:        mov     ax,[si+22]      ; x1 *= *key++
        !           304: endif
        !           305:        mul     x1
        !           306:        sub     ax,dx
        !           307:        jz      Core8Z
        !           308:        mov     x1,es
        !           309:        adc     x1,ax
        !           310: Core8done:
        !           311: 
        !           312:        add     x2,x1           ; x2 += x1
        !           313: 
        !           314:        xor     x0,x1           ; x0 ^= x1
        !           315:        xor     x3,x2           ; x3 ^= x2
        !           316: 
        !           317:        pop     dx
        !           318:        xor     x1,dx           ; x1 ^= s2
        !           319:        pop     dx
        !           320:        xor     x2,dx           ; x2 ^= s1
        !           321: 
        !           322: ife USELODS
        !           323:        lea     si,[si+24]
        !           324: endif
        !           325: 
        !           326:        ret     ; Used as a loop instruction!
        !           327: 
        !           328: Core5Z:
        !           329:        neg     x0
        !           330:        jnz     Core5Za
        !           331: if USELODS
        !           332:        sub     x0,[si-2]
        !           333: else
        !           334:        sub     x0,[si+12]
        !           335: endif
        !           336: Core5Za:
        !           337:        inc     x0
        !           338:        jmp     Core5done
        !           339: Core6Z:
        !           340:        neg     x3
        !           341:        jnz     Core6Za
        !           342: if USELODS
        !           343:        sub     x3,[si-2]
        !           344: else
        !           345:        sub     x3,[si+18]
        !           346: endif
        !           347: Core6Za:
        !           348:        inc     x3
        !           349:        jmp     Core6done
        !           350: Core7Z:
        !           351:        neg     x2
        !           352:        jnz     Core7Za
        !           353: if USELODS
        !           354:        sub     x2,[si-2]
        !           355: else
        !           356:        sub     x2,[si+20]
        !           357: endif
        !           358: Core7Za:
        !           359:        inc     x2
        !           360:        jmp     Core7done
        !           361: Core8Z:
        !           362:        neg     x1
        !           363:        jnz     Core8Za
        !           364: if USELODS
        !           365:        sub     x1,[si-2]
        !           366: else
        !           367:        sub     x1,[si+22]
        !           368: endif
        !           369: Core8Za:
        !           370:        inc     x1
        !           371:        jmp     Core8done
        !           372: Core9Z:
        !           373:        neg     x0
        !           374:        jnz     Core9Za
        !           375: if USELODS
        !           376:        sub     x0,[si-2]
        !           377: else
        !           378:        sub     x0,[si]
        !           379: endif
        !           380: Core9Za:
        !           381:        inc     x0
        !           382:        jmp     Core9done
        !           383: ; Special: compute into dx (zero on entry)
        !           384: Core10Z:
        !           385:        sub     dx,x3
        !           386:        jnz     Core10Za
        !           387: if USELODS
        !           388:        sub     dx,[si-2]
        !           389: else
        !           390:        sub     dx,[si+6]
        !           391: endif
        !           392: Core10Za:
        !           393:        inc     dx
        !           394: ;      jmp     Core10done
        !           395:        ret
        !           396: 
        !           397: 
        !           398: Finish:
        !           399: if USELODS
        !           400:        lodsw
        !           401: else
        !           402:        mov     ax,[si]         ; x0 *= *key++
        !           403: endif
        !           404:        mul     x0
        !           405:        sub     ax,dx
        !           406:        jz      Core9Z
        !           407:        mov     x0,es
        !           408:        adc     x0,ax
        !           409: Core9done:
        !           410: 
        !           411:        xchg    x1,x2
        !           412: if USELODS
        !           413:        lodsw
        !           414:        add     x1,ax
        !           415:        lodsw
        !           416:        add     x2,ax
        !           417: else
        !           418:        add     x1,[si+2]       ; x1 += *key++
        !           419:        add     x2,[si+4]       ; x2 += *key++
        !           420: endif
        !           421: 
        !           422: ; This is special: compute into dx, not x3
        !           423: if USELODS
        !           424:        lodsw
        !           425: else
        !           426:        mov     ax,[si+6]       ; x3 *= *key++
        !           427: endif
        !           428:        mul     x3
        !           429:        sub     ax,dx
        !           430:        mov     dx,es
        !           431:        jz      Core10Z
        !           432:        adc     dx,ax
        !           433: Core10done:
        !           434: 
        !           435:        ret
        !           436: 
        !           437:        endp
        !           438: 
        !           439: 
        !           440: ; Args are in, out, key
        !           441:        public  _Idea2
        !           442: _Idea2 proc far
        !           443:        cld
        !           444:        push    bp      ; Args start at [bp+6]
        !           445:        mov     bp,sp
        !           446:        push    si
        !           447:        push    di
        !           448:        push    ds      ; 6 more words here, so args are at [sp+12]
        !           449:        lds     si,[bp+6]       ; in
        !           450:        lodsw
        !           451:        xchg    ah,al
        !           452:        mov     dx,ax
        !           453:        lodsw
        !           454:        xchg    ah,al
        !           455:        mov     x1,ax
        !           456:        lodsw
        !           457:        xchg    ah,al
        !           458:        mov     x2,ax
        !           459:        lodsw
        !           460:        xchg    ah,al
        !           461:        mov     x3,ax
        !           462:        lds     si,[bp+14]      ; key
        !           463: 
        !           464:        mov     x0,dx
        !           465: 
        !           466:        call    Core
        !           467: 
        !           468:        mov     ax,x0
        !           469:        mov     bp,sp
        !           470:        les     di,[bp+16]
        !           471:        xchg    ah,al
        !           472:        stosw
        !           473:        mov     ax,x1
        !           474:        xchg    ah,al
        !           475:        stosw
        !           476:        mov     ax,x2
        !           477:        xchg    ah,al
        !           478:        stosw
        !           479:        mov     ax,x3
        !           480:        xchg    ah,al
        !           481:        stosw
        !           482: 
        !           483:        pop     ds
        !           484:        pop     di
        !           485:        pop     si
        !           486:        pop     bp
        !           487: 
        !           488:        ret
        !           489: 
        !           490:        endp
        !           491: 
        !           492: ; Okay, the basic plan for the CFB kernel is
        !           493: ; get x0,x1,x2,x3
        !           494: ; get key pointer
        !           495: ; call core
        !           496: ; get buffer pointers
        !           497: ;Loop:
        !           498: ; lodsw
        !           499: ; xor  ax,x0
        !           500: ; mov   x0,ax
        !           501: ; stosw
        !           502: ; lodsw
        !           503: ; xor  ax,x1
        !           504: ; mov  x0,ax
        !           505: ; stosw
        !           506: ; lodsw
        !           507: ; xor  ax,x2
        !           508: ; mov  x0,ax
        !           509: ; stosw
        !           510: ; lodsw
        !           511: ; xor  ax,x3
        !           512: ; mov  x3,ax
        !           513: ; stosw
        !           514: ; push buffer pointers
        !           515: ; get key pointer
        !           516: ; call core
        !           517: ; pop buffer pointers
        !           518: ; loop
        !           519: ; lodsw/xor/etc.
        !           520: ;
        !           521: ;
        !           522: ; This function is designed to go in the middle of a byte-granularity
        !           523: ; CFB engine.  It performs "len" encryptions of the IV, encrypting
        !           524: ; 8*(len-1) bytes from the source to the destination.  The idea is
        !           525: ; that you first xor any odd leading bytes, then call this function,
        !           526: ; then xor up to 8 trailing bytes.
        !           527: 
        !           528: ; The main loop in this is 38 instructions, plus the 336 for the core
        !           529: ; makes 374 total.  That's 46.75 instructions per byte.
        !           530: ; (It's the same for IdeaCFBx)
        !           531: 
        !           532: ; IV, key, plain, cipher, len
        !           533:        public  _IdeaCFB
        !           534: _IdeaCFB proc far       ; Args are at [sp+4]
        !           535:        cld
        !           536:        push    bp
        !           537:        push    si
        !           538:        push    di
        !           539:        push    ds      ; 8 more words here, so args are at [sp+12]
        !           540: ; To be precise, IV is at 12, key at 16, plain at 20,
        !           541: ; cipher at 24 and len at 28
        !           542:        mov     bp,sp
        !           543:        lds     si,[bp+12]      ; IV
        !           544: ; Load and byte-swap IV
        !           545:        mov     ax,[si]
        !           546:        xchg    ah,al
        !           547:        mov     x1,[si+2]
        !           548:        mov     x2,[si+4]
        !           549:        xchg    bh,bl
        !           550:        xchg    ch,cl
        !           551:        mov     dx,[si+6]
        !           552:        xchg    dh,dl
        !           553: 
        !           554:        lds     si,[bp+16]      ; Key
        !           555:        mov     x0,ax
        !           556:        mov     x3,dx
        !           557: 
        !           558:        call    Core
        !           559: IdeaCFBLoop:
        !           560: ;      mov     ax,x0
        !           561: ;      mov     bp,sp
        !           562: ;      dec     WORD PTR [bp+28]        ; Decrement count
        !           563: ;      jz      IdeaCFBEnd
        !           564: ;      lds     si,[bp+20]
        !           565: ;      les     di,[bp+24]
        !           566: ;      mov     x0,ax
        !           567: ; Alternate code: (which is faster?  Two moves or three segment overrides?)
        !           568:        mov     si,sp
        !           569:        dec     WORD PTR ss:[si+28]
        !           570:        jz      IdeaCFBEnd
        !           571:        les     di,ss:[si+24]
        !           572:        lds     si,ss:[si+20]
        !           573: 
        !           574:        lodsw
        !           575:        xchg    ah,al
        !           576:        xor     ax,x0
        !           577:        mov     x0,ax
        !           578:        xchg    ah,al
        !           579:        stosw
        !           580:        lodsw
        !           581:        xchg    ah,al
        !           582:        xor     ax,x1
        !           583:        mov     x1,ax
        !           584:        xchg    ah,al
        !           585:        stosw
        !           586:        lodsw
        !           587:        xchg    ah,al
        !           588:        xor     ax,x2
        !           589:        mov     x2,ax
        !           590:        xchg    ah,al
        !           591:        stosw
        !           592:        lodsw
        !           593:        xchg    ah,al
        !           594:        xor     ax,dx
        !           595:        mov     dx,ax
        !           596:        xchg    ah,al
        !           597:        stosw
        !           598: 
        !           599: ;      mov     ax,x0
        !           600: ;      mov     bp,sp
        !           601: ;      mov     [bp+20],si      ; Save source offset
        !           602: ;      mov     [bp+24],di      ; Save destination offset
        !           603: ;      lds     si,[bp+16]      ; Key
        !           604: ;      mov     x0,ax           ; Get x0 in place for another iteration
        !           605: ; Alternate code for the above: (which is faster?  One move or three ss:?)
        !           606:        mov     ax,si
        !           607:        mov     si,sp
        !           608:        mov     ss:[si+20],ax
        !           609:        mov     ss:[si+24],di
        !           610:        lds     si,ss:[si+16]
        !           611: 
        !           612:        mov     x3,dx           ; Get x3 in place
        !           613:        mov     ax,OFFSET IdeaCFBLoop
        !           614:        push    ax
        !           615:        jmp     Core
        !           616: 
        !           617: IdeaCFBEnd:
        !           618: ;      lds     si,[bp+12]
        !           619:        lds     di,ss:[si+12]   ; Get IV for writing back
        !           620: 
        !           621:        mov     ax,x0
        !           622:        xchg    ah,al
        !           623:        mov     [di],ax         ; Use stosw?
        !           624:        xchg    bh,bl
        !           625:        xchg    ch,cl
        !           626:        mov     [di+2],x1
        !           627:        mov     [di+4],x2
        !           628:        xchg    dh,dl
        !           629:        mov     [di+6],dx
        !           630: 
        !           631:        pop     ds
        !           632:        pop     di
        !           633:        pop     si
        !           634:        pop     bp
        !           635: 
        !           636:        ret
        !           637: 
        !           638:        endp
        !           639: 
        !           640: ; This decoding step is similar, except that instead of
        !           641: ;      lods
        !           642: ;      xor     x0,ax
        !           643: ;      mov     ax,x0
        !           644: ;      stos
        !           645: ; the feedback step is
        !           646: ;      lods
        !           647: ;      xchg    x0,ax
        !           648: ;      xor     ax,x0
        !           649: ;      stos
        !           650: 
        !           651: ; IV, key, cipher, plain, len
        !           652:        public  _IdeaCFBx
        !           653: _IdeaCFBx proc far       ; Args are at [sp+4]
        !           654:        cld
        !           655:        push    bp
        !           656:        push    si
        !           657:        push    di
        !           658:        push    ds      ; 8 more words here, so args are at [sp+12]
        !           659:        mov     bp,sp
        !           660:        lds     si,[bp+12]      ; IV
        !           661: ; Load and byte-swap IV
        !           662:        mov     ax,[si]
        !           663:        xchg    ah,al
        !           664:        mov     x1,[si+2]
        !           665:        mov     x2,[si+4]
        !           666:        xchg    bh,bl
        !           667:        xchg    ch,cl
        !           668:        mov     dx,[si+6]
        !           669:        xchg    dh,dl
        !           670: 
        !           671:        lds     si,[bp+16]      ; Key
        !           672:        mov     x0,ax
        !           673:        mov     x3,dx
        !           674: 
        !           675:        call    Core
        !           676: IdeaCFBxLoop:
        !           677: ;      mov     ax,x0
        !           678: ;      mov     bp,sp
        !           679: ;      dec     WORD PTR [bp+28]        ; Decrement count
        !           680: ;      jz      IdeaCFBxEnd
        !           681: ;      lds     si,[bp+20]
        !           682: ;      les     di,[bp+24]
        !           683: ;      mov     x0,ax
        !           684: ; Alternate code: (which is faster?  Two moves or three segment overrides)
        !           685:        mov     si,sp
        !           686:        dec     WORD PTR ss:[si+28]
        !           687:        jz      IdeaCFBxEnd
        !           688:        les     di,ss:[si+24]
        !           689:        lds     si,ss:[si+20]
        !           690: 
        !           691:        lodsw
        !           692:        xchg    ah,al
        !           693:        xchg    x0,ax
        !           694:        xor     ax,x0
        !           695:        xchg    ah,al
        !           696:        stosw
        !           697:        lodsw
        !           698:        xchg    ah,al
        !           699:        xchg    x1,ax
        !           700:        xor     ax,x1
        !           701:        xchg    ah,al
        !           702:        stosw
        !           703:        lodsw
        !           704:        xchg    ah,al
        !           705:        xchg    x2,ax
        !           706:        xor     ax,x2
        !           707:        xchg    ah,al
        !           708:        stosw
        !           709:        lodsw
        !           710:        xchg    ah,al
        !           711:        xchg    dx,ax
        !           712:        xor     ax,dx
        !           713:        xchg    ah,al
        !           714:        stosw
        !           715: 
        !           716: ;      mov     ax,x0
        !           717: ;      mov     bp,sp
        !           718: ;      mov     [bp+20],si      ; Save source offset
        !           719: ;      mov     [bp+24],di      ; Save destination offset
        !           720: ;      lds     si,[bp+16]      ; Key
        !           721: ;      mov     x0,ax           ; Get x0 in place for another iteration
        !           722: ; Alternate code for the above: (which is faster?  One move or three ss:?)
        !           723:        mov     ax,si
        !           724:        mov     si,sp
        !           725:        mov     ss:[si+20],ax
        !           726:        mov     ss:[si+24],di
        !           727:        lds     si,ss:[si+16]
        !           728: 
        !           729:        mov     x3,dx           ; Get x3 in place
        !           730:        mov     ax,OFFSET IdeaCFBxLoop
        !           731:        push    ax
        !           732:        jmp     Core
        !           733: 
        !           734: IdeaCFBxEnd:
        !           735: ;      lds     si:[bp+12]
        !           736:        lds     di,ss:[si+12]   ; Get IV for writing back
        !           737: 
        !           738:        mov     ax,x0
        !           739:        xchg    ah,al
        !           740:        mov     [di],ax         ; Use stosw?
        !           741:        xchg    bh,bl
        !           742:        xchg    ch,cl
        !           743:        mov     [di+2],x1
        !           744:        mov     [di+4],x2
        !           745:        xchg    dh,dl
        !           746:        mov     [di+6],dx
        !           747: 
        !           748: 
        !           749:        pop     ds
        !           750:        pop     di
        !           751:        pop     si
        !           752:        pop     bp
        !           753: 
        !           754:        ret
        !           755: 
        !           756:        endp
        !           757: 
        !           758: 
        !           759: 
        !           760: 
        !           761:        end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.