7.3 Unconditional Transfer of Control (jmp)

The jmp ( jump) instruction unconditionally transfers control to another point in the program. There are three forms of this instruction: a direct jump and two indirect jumps. These instructions take the following forms:

jmp label;
     jmp( reg32 );
     jmp( mem32 );

The first instruction is a direct jump above. For direct jumps you normally specify the target address using a statement label. The label appears either on the same line as an executable machine instruction or by itself on a line preceding an executable machine instruction. The direct jump is completely equivalent to a goto statement in a high-level language.[105]

Here's an example:

<< statements >>
          jmp laterInPgm;
               .
               .
               .
laterInPgm:
          << statements >>

The second form of the jmp instruction given earlier—jmp( reg32 );—is a register indirect jump instruction. This instruction transfers control to the instruction whose address appears in the specified 32-bit general-purpose register. To use this form of the jmp instruction, you must load a 32-bit register with the address of some machine instruction prior to the execution of the jmp. You could use this instruction to implement a state machine by loading a register with the address of some label at various points throughout your program and then use a single indirect jump at a common point to transfer control to one of those labels. The short sample program in Example 7-3 demonstrates how you could use the jmp in this manner.

Example 7-3. Using register-indirect jmp instructions

program regIndJmp;
#include( "stdlib.hhf" );

static
    i:int32;

begin regIndJmp;

    // Read an integer from the user and set ebx to
    // denote the success or failure of the input.

    try

        stdout.put( "Enter an integer value between 1 and 10: " );
        stdin.get( i );
        mov( i, eax );
        if( eax in 1..10 ) then

            mov( &GoodInput, ebx );

        else

            mov( &valRange, ebx );

        endif;

      exception( ex.ConversionError )

        mov( &convError, ebx );

      exception( ex.ValueOutOfRange )

        mov( &valRange, ebx );

    endtry;

    // Okay, transfer control to the appropriate
    // section of the program that deals with
    // the input.

    jmp( ebx );

    valRange:
        stdout.put( "You entered a value outside the range 1..10" nl );
        jmp Done;

    convError:
        stdout.put( "Your input contained illegal characters" nl );
        jmp Done;

    GoodInput:
        stdout.put( "You entered the value ", i, nl );

    Done:


end regIndJmp;

The third form of the jmp instruction given earlier is a memory-indirect jmp. This form of the jmp instruction fetches the double-word value from the memory location and jumps to that address. This is similar to the register-indirect jmp except the address appears in a memory location rather than in a register. Example 7-4 demonstrates a rather trivial use of this form of the jmp instruction.

Example 7-4. Using memory-indirect jmp instructions

program memIndJmp;
#include( "stdlib.hhf" );

static
    LabelPtr:dword := &stmtLabel;

begin memIndJmp;

    stdout.put( "Before the JMP instruction" nl );
    jmp( LabelPtr );

        stdout.put( "This should not execute" nl );

    stmtLabel:

        stdout.put( "After the LabelPtr label in the program" nl );

end memIndJmp;

Warning

Unlike the HLA high-level control structures, the low-level jmp instructions can cause you a lot of trouble. In particular, if you do not initialize a register with the address of a valid instruction and you jump indirectly through that register, the results are undefined (though this will usually cause a general protection fault). Similarly, if you do not initialize a double-word variable with the address of a legal instruction, jumping indirectly through that memory location will probably crash your program.



[105] Unlike high-level languages, where your instructors usually forbid you to use goto statements, you will find that the use of the jmp instruction in assembly language is essential.