assembly: LOOP, JMP & LABELS jbwyatt.com

.. LABELS

   A label is a way to indicate a memory address that can be looped 
   to or jumped to

   0100: EB 02                            jmp LAB2
   0102:                           LAB1:
   0102: B0 03                            mov al, 3                                   
   0104: 04 19                     LAB2:  add al, 25
   0106: FE C0                            inc al
   0108: FE C0                            inc al
   010A: EB F6                            jmp LAB1
           

.. JMP instruction

         JMP transfers control to a memory location indicated by a LABEL
    
        0100:                         LABEL:                                       
        0100: B0 03                        mov al, 3
        0102: 04 19                        add al, 25
        0104: EB FA                        jmp LABEL
    
      LABEL is indicated in the SYMBOL TABLE
      LABEL is 100h
      
      Explain 'EB FA' at 0104.
      
    

.. LOOP and the CX Register

 The LOOP instruction creates a counting loop
  Syntax: LOOP target

  Logic:
   1. CX <- CX – - 1
   2. If CX > 0, jump to target

  Implementation:
   The assembler calculates the distance, in bytes,
   between the current location and the offset of the target label.
   It is called the relative offset.

   The relative offset is added to IP as an offset.

   Don't use:  CX, CL, CH  for anything else inside the loop!!!

... mov AL, 0 ; init mov AH, 1 ; number to be added mov CX, 5 ; reps L1: add AL, AH ; sum = sum + num inc AH ; num++ loop L1 ; decrement THEN compare to zero What is in AL? AH? AX?

.. Example Program Code

    ; Wyatt, 11/11/2011
    ;
    ; EXPLAIN CODE PURPOSE AND ALGORITHM 
    ; ----------------------------------
    
    ; FILE WITH MACROS & PROCS
    ; ------------------------ 
    include emu8086.inc       
    
    ; ADDRESS WHERE CODE WILL BE LOCATED
    ; ----------------------------------
    org 100h             
    
    ; CODE
    ; ----
        mov cx, 5
        L1:
           PRINT "CX has the value of "
           mov ax, cx
           call PRINT_NUM
           PRINTN
        loop L1       
    ret
    
    ; DATA
    ; ----                
    
    ; PROCEDURES (call)
    ; ----------
    DEFINE_SCAN_NUM		  ; reads signed number from keyboard into CX
    DEFINE_PRINT_STRING   ; print 0 terminated string, address in DS:SI
    DEFINE_PRINT_NUM      ; prints AX signed
    DEFINE_PRINT_NUM_UNS  ; prints AX unsigned - required for print_num.
    end
    
    EXAMPLE ASSEMBLY CODE (from emu) ===================== ; print result in binary: mov cx, 8 print: mov ah, 2 ; print function. mov dl, '0' test bl, 10000000b ; test first bit. jz zero mov dl, '1' zero: int 21h shl bl, 1 loop print Same program with machine code ====================================================================== [LINE] LOC: MACHINE CODE SOURCE ====================================================================== [ 14] : ; print result in binary: [ 15] 0109: B9 08 00 mov cx, 8 [ 16] 010C: B4 02 print: mov ah, 2 ; print function. [ 17] 010E: B2 30 mov dl, '0' [ 18] 0110: F6 C3 80 test bl, 10000000b ; test first bit. [ 19] 0113: 74 02 jz zero [ 20] 0115: B2 31 mov dl, '1' [ 21] 0117: CD 21 zero: int 21h [ 22] 0119: D0 E3 shl bl, 1 [ 23] 011B: E2 EF loop print DOCUMENTED ===================== ; prints the value of the byte in bl in binary ; repetition value MOV CX, 8 ; in a loop, print the leftmost bit of bl each time thru NEXT: MOV AH, 2 ; with int21h, this invokes print function MOV DL, '0' ; default to a zero to print (int 21h prints what is in dl) ;test the leftmost bit by anding (test) the bl reg with the mask ;if the leftmost bit is zero, the zero flag wiill be set because ;0 and 1 => 0, but if it is 1, the zero flad will not be set TEST BL, 10000000B ; now, either jmp & print '0', or fall thru and print '1' JZ PRINT MOV DL, '1' ; DL CONTAINS THE CHARACTER TO PRINT PRINT: INT 21H SHL BL, 1 loop NEXT

.. LOOP Machine Code

   The following loop calculates the sum of the integers
         5 + 4 + 3 + 2 + 1:

   ASSEMBLY CODE:
   ==============
         mov  AX, 0
         mov  CX, 5
     L1: add  AX, CX
         loop L1
 
      where is the sum?
      what value is in CX at the end?
      why are we adding CX?
      
   MACHINE CODE:
   =============
      offset     machine code        source code
      ------     ------------      -----------------
    0100:        B8 00 00           mov  AX,  0
    0103:        B9 05 00           mov  CX, 5
    0106:        03 C1          L1: add  AX, CX
    0108:        E2 FC              loop L1
    010A:                               
   Looking at the LOOP machine code, we see that –-4(FC) is added
   to the IP (010A) causing a jump to location 0106.
   
   Explain.

.. Jumps: creating an "if / else"

; if / else
; if number > 32767
;      print # as an unsigned
; else
;      print # signed
;
 
include emu8086.inc        
org 100h
        ; get value
        mov ax, 0
        call SCAN_NUM
        PRINTN
            
        ; calculate            
        add ax, cx
                   
        ; if the sum in ax is big  
        cmp ax, 32767
        ja UNSIGNED   ;ja unsigned, jg signed

        ; print # signed  
        call PRINT_NUM
        PRINTN " SIGNED"
        jmp CONT 
        
        ; print # signed                 
UNSIGNED:           
        call PRINT_NUM_UNS    
        PRINTN " UNSIGNED"    
            
CONT:          
        PRINTN
        PRINTN "done"  
        RET               

; PROCEDURES (call)
; ----------
DEFINE_SCAN_NUM       ; reads signed number from keyboard into CX
DEFINE_PRINT_NUM      ; prints AX signed
DEFINE_PRINT_NUM_UNS  ; prints AX unsigned - required for print_num.

END
 

.. Looping more than +127 or -128 bytes (emu adjusts)

LOOP instruction is limited to a one byte offset   
Since the offset can be forward or back, the offset must be signed.
   [ in emu8086, it adjusts and increases the offset size as needed ] 

The signed numerical limit of one byte in decimal is ______  to ________

Loop less than 128 bytes ========================= 0100: B9 05 00 mov CX, 5 ; holds counter for loop 0103: L1: 0103: 50 56 EB 03 0D 0A 00 BE 07 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 011D: 50 56 EB 03 0D 0A 00 BE 21 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 0137: 50 56 EB 03 0D 0A 00 BE 3B 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 0151: 50 56 EB 03 0D 0A 00 BE 55 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 016B: E2 96 loop L1 016D: C3 ret 16dh = 365 96h = -106 103h = 259
Loop greater than 128 bytes =========================== 0100: B9 05 00 mov CX, 5 ; holds counter for loop 0103: L1: 0103: 50 56 EB 03 0D 0A 00 BE 07 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 011D: 50 56 EB 03 0D 0A 00 BE 21 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 0137: 50 56 EB 03 0D 0A 00 BE 3B 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 0151: 50 56 EB 03 0D 0A 00 BE 55 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 016B: 50 56 EB 03 0D 0A 00 BE 6F 01 2E 8A PRINTN 04 3C 00 74 07 46 B4 0E CD 10 EB F2 5E 58 0185: 49 E3 03 E9 78 FF loop L1 018B: C3 ret 49 DEC CX E3 JCXZ needs to go back 136 bytes (88 hex), so -136 = FF78 03 E9 is part of the address for the segment offset
JMP is an unconditional jump to a label anywhere within the same procedure. === Can jump anywhere within 32 bit address space Syntax: JMP target Example: top: . . jmp top Ex: suppose we want to do: INCLUDE EMU8086.INC ORG 100h jmp CODE Num = 7 CODE: mov CX, COUNT ABC: ;lots of instructions that assembles into ; more than 128 bytes of code loop ABC ;NO! can't do this RET
We do instead: ------- INCLUDE EMU8086.INC ORG 100h jmp CODE Num = 7 CODE: mov CX, Num ABC: ; ; lots of code ; cmp CX, 0 je CONT ; end loop dec CX jmp ABC ; keep looping CONT: ; ; continue code ; RET ===== OR... ================== INCLUDE EMU8086.INC ORG 100h jmp CODE Num = 7 CODE: mov CX, Num ;set up the loop count ABC: ; ... ;lots of code ; ... dec CX ;subtract 1 from the CX (mimic the LOOP instruction) jne ABC ;keep looping if CX is NOT zero (mimic LOOP) ; ... ; continue code here when done looping ; ... RET