| UMBC CMSC 211 |
i = some expression
if ( i == 1)
{
some statements0
}
else if ( i == 2 )
{
some statements1
}
else if( i == 3 )
{
some statements2
}
else
{
some statements3
}
Yes, it is legal, but not that efficient. You know a better way:
switch (some expression)
{
case 1:
some statements0
break;
case 2:
some statements1
break;
case 3:
some statements2
break;
default:
some statements3
break;
}
For each one of those cases, we need a label to for a JE instruction. If we can assume for the moment that we have an expression that is evaluate, and the results are stored in the AL register, then my example looks like this:
cmp AL, 1
je L1
cmp AL, 2
je L2
cmp AL, 3
je L3
jmp LDefault
L1: some statements0
jmp SwitchDone
L2: some statements1
jmp SwitchDone
L3: some statements2
jmp SwitchDone
LDefault:
some statements3
jmp SwitchDone
SwitchDone:
Whatever comes next
So what did we do? First there is a unique label for each case condition. There is also a label for the default condition. Then we compare the register AL with each condition, one at a time, and jump to the label if that condition is met. Finally, if we reach this far, we jump to the default statements.
Inside each case statement in C there is a break. In assembly, we have a jmp to the label that comes after the switch code, or in this case SwitchDone.
So what was the author talking about. There is something called a jump table. A jump table is an array of addresses that will be used with a jmp instruction. We have to have a collection of addresses that we store in an array. Then we need that collection ordered, in such a way, that when we want the first one, we have an indicator that will equal the first array slot (remember it must equal zero, because everything in a computer is zero-based.) Then next one must have an indicator of one, the one after that must have an indicator or two, etc. When that is met, then we can use a jump table. The jump indicatior must be multipled by two, since we are incrementing by two bytes in a word array. Assume that the indicator is in register BX. Now we can have something like:
jmp TableLookup
jLabels DW L1, L2, L3, Default
TableLookup:
cmp BX, 0
jb Default
cmp BX, 3
ja Default ;Now we have a valid indicator
shl BX, 1 ;Lazy multiply
jmp [jLabels + BX]
L1: some statements0
jmp TableDone
L2: some statements1
jmp TableDone
L3: some statements2
jmp TableDone
Default:
some statements3
TableDone:
Whatever comes next
If you have the situation where you have most of the values in sequence, but one or two are missing, then for those missing ones, you also jump to the Default label.
Also, if you have the situation where you have a range of values that does not start at zero, say 42 to 46, then make the jmp like this:
jmp [jLabels + BX - 42]