7.1.1 Unconditional Jumps

Jumps in assembler programs are either conditional or unconditional. The assembler executes conditional jumps only when the jump condition is true. You use the JMP instruction to jump unconditionally to a specified address. Its single operand contains the target address, which can be short, near, or far.

Unconditional jumps are often used to skip over code that should not be executed, as shown in this example.

; Handle one case

label1: .

.

.

jmp continue

; Handle second case

label2: .

.

.

jmp continue

.

.

.

continue:

The distance of the target from the jump instruction and the size of the operand determine the assembler's encoding of the instruction. The larger the distance, the more bytes the assembler uses to code the instruction. In previous versions of MASM, unconditional NEAR jumps sometimes generate inefficient code. Unspecified FAR jumps result in phase errors.

7.1.1.1 Jump Optimizing

Beginning with MASM 6.0, the assembler determines the smallest encoding possible for the direct unconditional jump. You do not specify a distance operator, so you do not have to determine the correct distance of the jump. If you do specify a distance, however, and it is too short, the assembler generates an error. A specified distance that is too long causes a less efficient jump to be generated than the assembler would generate if the distance had not been specified.

MASM 6.0 optimizes jumps if the following conditions are met:

You do not specify SHORT, NEAR, FAR, NEAR16, NEAR32, FAR16, FAR32, or PROC as the distance of the target.

The target of the jump is not external and is in the same segment as the jump instruction. If the target is in a different segment (but in the same group), it is treated as if external.

If these two conditions are met, MASM uses the instruction, distance, and size of the operand to determine how best to optimize the encoding for the jump. No syntax changes are necessary.

NOTE:

This information about jump optimizing also applies to conditional jumps on the 80386/486.

7.1.1.2 Indirect Operands

Indirect operands specify a register or data memory location that holds the address of the jump's destination. Indirect operands differ from the operands of direct jumps by being a memory expression instead of an immediate expression. For indirect jumps, you can specify the encoding for the instruction by giving the size (WORD, DWORD, or FWORD) attributes for the operand.

The default rules are based on the .MODEL and the default segment size.

jmp [bx] ; Uses .MODEL and segment size

; defaults

jmp WORD PTR [bx] ; A NEAR16 indirect call

If the indirect operand is a register, the jump is always a NEAR16 jump for a 16-bit register, and FAR32 for a 32-bit register:

jmp bx ; NEAR16 jump

jmp ebx ; FAR32 jump

A DWORD indirect operand, however, is an ambiguous case:

jmp DWORD PTR [var] ; A NEAR32 jump in a 32-bit segment;

; a FAR16 jump in a 16-bit segment

In this case, you must define a type with TYPEDEF to specify the indirect operand.

NFP TYPEDEF PTR NEAR32

FFP TYPEDEF PTR FAR16

jmp NFP PTR [var] ; NEAR32 indirect jump

jmp FFP PTR [var] ; FAR16 indirect jump

You can use an unconditional jump as a form of conditional jump by specifying the address in a register or indirect memory operand. Also, you can use indirect memory operands to construct jump tables that work like C switch statements,

Pascal CASE statements, or Basic ON GOTO, ON GOSUB, or SELECT CASE statements, as shown in this example:

NPVOID TYPEDEF NEAR PTR VOID

.DATA

ctl_tbl NPVOID extended, ; Null key (extended code)

ctrla, ; Address of CONTROL-A key routine

ctrlb ; Address of CONTROL-B key routine

.CODE

.

.

.

mov ah, 8h ; Get a key

int 21h

cbw ; Stretch AL into AX

mov bx, ax ; Copy

shl bx, 1 ; Convert to address

jmp ctl_tbl[bx] ; Jump to key routine

extended:

mov ah, 8h ; Get second key of extended key

int 21h

. ; Use another jump table

. ; for extended keys

.

jmp next

ctrla: . ; CONTROL-A code here

.

.

jmp next

ctrlb: . ; CONTROL-B code here

.

.

jmp next

.

.

next: . ; Continue

In this example, the indirect memory operands point to addresses of routines for handling different keystrokes.