Labels and Jumps
Labels
Labels are names which are used to identify various pieces of code. In effect they give a name to a particular location in an assembler program. In assembler, a label consists of a name followed immediately by a colon. Any letter or number both upper and lower case as well as the underscore, may be used in label names. Names are not case sensitive, like the rest of assembler (mov Ah,dL is the same as MOV AH,DL). The following are all valid label names:
start: |
loop1: |
read_a_key: |
ANY_Label_3: |
L1: |
To put a label in your code is simple, just put in it the middle of your code with instructions either side of it. Remember, though, no two labels can have the same name, and reserved words cannot be used as label names eg. you can’t have a label “mov:”, use “move:” instead. Below is our program from Tut2 with labels inserted:
Output_char: MOV AH,02 MOV DL,"!" INT 21h |
; This point in the code is now called "Output_char". ; To select subfunction 2, move the appropriate number, 2, to AH. ; In the interrupt list, it says that the character to output should be ; in register DL. So we move the character to DL. ; Finally when all the registers are set as required, we call the interrupt. |
Exit: MOV AH,4Ch MOV AL,00 INT 21h |
; Labels should be relevant to the code after them. ; Select the subfunction. ; Select a return value (optional but recommended). ; Call the DOS interrupt. |
Jumps and Conditional Execution
The principle usage of labels in assembler is to perform conditional execution, the equivalent of IF statements in most high level languages. In assembler one has to have two instructions to have conditional execution. The first instruction is nearly always the CMP instruction which compares two values. If they are equal one of the CPU’s flags, known as the zero flag is set (Basically the CMP instruction gets the difference between two quantities and see’s if it is zero or not). The second instruction necessary for conditional execution is the JMP instruction or a derivitive thereof. These instructions shall now be examined individually.
JMP
The JMP instruction in assembler causes the program execution to continue from a certain point. The JMP instruction has just one operand which is either the address of the point in the program where execution is to start (very very rare) or a label. Consider the following piece of code:
start: mov ah,08 int 21h mov bl,al JMP output mov ah,01 int 21h output: mov dl,"(" mov ah,02 int 21h mov dl,bl int 21h mov dl,")" int 21h exit: mov ah,4ch mov al,00 int 21h |
; sub-function 8 - read a character ; call interrupt ; save the key read in bl. ; a jump instruction causes the program to start running now from the ; output label, skipping out the next two lines. ; These never get executed... ; execution continues here ; output a "(" ; Then output the character read still held in bl ; Last output a ")" ; Terminate the program |
The code executes in a linear fashion until it gets to the jmp command from which it execution continues with the statement “mov dl,bl”. The intermediate two lines never get executed.
JZ
The JZ instruction is a form of the JMP instruction except that the jump occurs only when the zero flag is set. The instruction is read as “Jump if Zero”.
JNZ
The JNZ instruction is the opposite of the JZ instruction in that the jump occurs when the zero flag is NOT set. It is read as “Jump if Not Zero”.
CMP
The CMP(compare) instruction is used two compare two values and to act upon the result of that comparison. For now, we shall concern ourselves with the two most basic results of the comparison, whether the quantities are equal or not. The compare instruction essentially subtracts the two values passed to it and sets the zero flag if the difference is zero i.e. the two quantities are equal. A combination of the CMP and the JMP instructions can be used to implement the assembler equaivalent of a basic if statement.
Consider the following example which will read in a key and tell the user if he pressed escape (ASCII code 27):
start: mov ah,08 int 21h CMP al,27 JNZ not_escape is_escape: mov ah,02 mov dl,"E" int 21h mov dl,"S" int 21h mov dl,"C" int 21h not_escape: mov ah,4ch mov al,00 int 21h |
; again sub-function 8 ; read the character ; compare it to the escape character ; if it is not equal (difference is not zero (NZ)) then go to not_escape ; otherwise this code gets executed. ; subfunction 2 - output a character. ; output letter "E" ; then output "S". (NOTE: 02 remains in ah register so no need to keep moving it) ; finally output "C" ; if any other key is pressed execution continues here ; exit the program. |