In this article, I will explain in detail the implementation of the switch statement in assembly language, along with an analysis of the provided code example.
Basic Characteristics of the Switch Statement
The switch statement has the following significant differences compared to the if/elseif structure:
- Only performs equality comparisons (using je/jne instructions)
- Uses a series of comparison-jump pairs
- The last jump is an unconditional jump to default or the end of the switch
- If there is a break in the case block, it generates an unconditional jump (jmp)
Code Example Analysis
Disassembled Structure of the Switch Statement
switch(c)
00411A66 mov eax, dword ptr [c] ; Load the value of c into eax
00411A69 mov dword ptr [ebp-0EBh], eax ; Debug version may save to local variable
00411A6F mov dword ptr [ebp-0E8h], 0 ; Initialize comparison value (debug version feature)
00411A76 je myfunction+63h (411A83h) ; Compare c==0, jump to case 0
00411A78 cmp dword ptr [ebp-0E8h], 1 ; Compare c==1
00411A7F je myfunction+70h (411A90h) ; Jump to case 1
00411A81 jmp myfunction+7eh (411A9Eh) ; Unconditional jump to default
This code demonstrates the core structure of the switch statement:
- Load the value to be compared (c)
- A series of equality comparisons (using je)
- The final unconditional jump (default)
Implementation of Case Blocks
case 0:
printf("c>0");
00411A83 push offset string "c>0" (4240DCh) ; Push parameter onto stack
00411A88 call @ILT+1300(printf) (411519h) ; Call printf
00411A8D add esp, 4 ; Clean up stack
case 1:
printf("c>10 && c<100");
00411A90 push offset string "c>10 && c<100" (424288h)
00411A95 call @ILT+1300(printf) (411519h)
00411A9A add esp, 4
break;
00411A9D jmp myfunction+8ch (411AACh) ; Unconditional jump generated by break
default:
printf("c>10 && c<100");
00411A9E push offset string "c>10 && c<100" (424288h)
00411AA3 call @ILT+1300(printf) (411519h)
00411AA8 add esp, 4
Characteristics of case blocks:
- If there is no break, it will “fall through” to the next case
- With a break, it generates an unconditional jump (jmp) to skip subsequent cases
- The default block does not require special handling, just a different execution position
General Pattern of the Switch Statement
In assembly, the switch statement typically follows this pattern:
mov eax, [switch_var] ; Load switch variable
cmp eax, case1_value
je case1_label
cmp eax, case2_value
je case2_label
; ...more case comparisons...
jmp default_label ; Default jump to default
case1_label:
; case 1 code
jmp end_switch ; If there is a break
case2_label:
; case 2 code
; No break will continue executing the next case
default_label:
; default code
end_switch:
; End of switch
Key Points Summary
- Equality Comparison: The switch only uses je/jne for equality comparisons, unlike if which can use various conditions (jg/jl, etc.)
- Jump Table: For cases with many options, the compiler may use a jump table for optimization, but the basic principle remains the same
- Break Implementation: Achieved through unconditional jumps (jmp)
- Default Handling: The last unconditional jump implements the default logic
- Case Fall Through: Without a break, the next case’s code will execute sequentially
- Debug Version Features: The debug version may have additional variable saving operations, which do not affect logic
Performance Considerations
- When there are many consecutive cases, the compiler may generate a jump table (indirect jump), which is more efficient
- For a small number of cases, use a series of cmp/je pairs
- Switch is usually more efficient than an equivalent if/elseif chain, especially with many cases
This structure makes the switch statement an efficient choice for handling multiple branches, especially in cases with dense and continuous value ranges.