Write a piece of C code, including if / else, while, for, switch:
#include <stdio.h> void IF(); void WHILE(); void FOR(); void SWITCH(); int main(void) { IF(); WHILE(); FOR(); SWITCH(); return 0; } void IF() { int a = 1; if (a == 2) a++; else a--; } void WHILE() { int b=1; while (b != 2) b++; } void FOR() { int c = 1; for (int i = 2; i < 3; i++) c++; int i = 4; i = 5; } void SWITCH() { int a = 1; int b; switch (a){ case 2: b = 3; break; case 4: b = 5; break; default: a = 6; break; } b++; }
After compiling, the assembly code is obtained by IDA:
IF:
.text:00000000004015DC public sub_4015DC .text:00000000004015DC sub_4015DC proc near ; CODE XREF: main+D↑p .text:00000000004015DC .text:00000000004015DC var_4 = dword ptr -4 .text:00000000004015DC .text:00000000004015DC push rbp .text:00000000004015DD mov rbp, rsp .text:00000000004015E0 sub rsp, 10h .text:00000000004015E4 mov [rbp+var_4], 1 .text:00000000004015EB cmp [rbp+var_4], 2 ;[rbp+var_4]Minus two .text:00000000004015EF jnz short loc_4015F7 ;Nonzero,Jump to loc_4015E7 .text:00000000004015F1 add [rbp+var_4], 1 ;[rbp+var_4]add one-tenth .text:00000000004015F5 jmp short loc_4015FB ;Jump To loc_4015FB .text:00000000004015F7 ; --------------------------------------------------------------------------- .text:00000000004015F7 .text:00000000004015F7 loc_4015F7: ; CODE XREF: sub_4015DC+13↑j .text:00000000004015F7 sub [rbp+var_4], 1 .text:00000000004015FB .text:00000000004015FB loc_4015FB: ; CODE XREF: sub_4015DC+19↑j .text:00000000004015FB nop .text:00000000004015FC add rsp, 10h .text:0000000000401600 pop rbp .text:0000000000401601 retn .text:0000000000401601 sub_4015DC endp
In assembly code, while first jumps to a later position, then executes conditional judgment, then jumps back when satisfied, and then proceeds to the place of conditional judgment after executing something sequentially. Until the conditions are not satisfied, do not jump back, the order of execution..text:0000000000401602 public WHILE .text:0000000000401602 WHILE proc near ; CODE XREF: main+12↑p .text:0000000000401602 .text:0000000000401602 var_4 = dword ptr -4 .text:0000000000401602 .text:0000000000401602 push rbp .text:0000000000401603 mov rbp, rsp .text:0000000000401606 sub rsp, 10h .text:000000000040160A mov [rbp+var_4], 1 .text:0000000000401611 jmp short loc_401617 .text:0000000000401613 ; --------------------------------------------------------------------------- .text:0000000000401613 .text:0000000000401613 loc_401613: ; CODE XREF: WHILE+19↓j .text:0000000000401613 add [rbp+var_4], 1 .text:0000000000401617 .text:0000000000401617 loc_401617: ; CODE XREF: WHILE+F↑j .text:0000000000401617 cmp [rbp+var_4], 2 ;[rbp+var_4]Minus two .text:000000000040161B jnz short loc_401613 ;Non-zero, jump to loc_401613 .text:000000000040161D nop .text:000000000040161E add rsp, 10h .text:0000000000401622 pop rbp .text:0000000000401623 retn .text:0000000000401623 WHILE endp
FOR:
for loops in assembly code, in fact, are similar to while loops..text:0000000000401624 public FOR .text:0000000000401624 FOR proc near ; CODE XREF: main+17↑p .text:0000000000401624 .text:0000000000401624 var_C = dword ptr -0Ch .text:0000000000401624 var_8 = dword ptr -8 .text:0000000000401624 var_4 = dword ptr -4 .text:0000000000401624 .text:0000000000401624 push rbp .text:0000000000401625 mov rbp, rsp .text:0000000000401628 sub rsp, 10h .text:000000000040162C mov [rbp+var_4], 1 .text:0000000000401633 mov [rbp+var_8], 2 .text:000000000040163A jmp short loc_401644 .text:000000000040163C ; --------------------------------------------------------------------------- .text:000000000040163C .text:000000000040163C loc_40163C: ; CODE XREF: FOR+24↓j .text:000000000040163C add [rbp+var_4], 1 .text:0000000000401640 add [rbp+var_8], 1 .text:0000000000401644 .text:0000000000401644 loc_401644: ; CODE XREF: FOR+16↑j .text:0000000000401644 cmp [rbp+var_8], 2 .text:0000000000401648 jle short loc_40163C .text:000000000040164A mov [rbp+var_C], 4 .text:0000000000401651 mov [rbp+var_C], 5 .text:0000000000401658 nop .text:0000000000401659 add rsp, 10h .text:000000000040165D pop rbp .text:000000000040165E retn .text:000000000040165E FOR endp
Another impression: In C, there are two i variables, one scope is the whole function, the other scope is only the inner block. But in assembler code, they are only regarded as two different variables, and there is no difference except that the scope of these two variables is the whole function. In assembly code, it seems that there is no such thing as "inner block". if/else, while, for code, although in C, seems to be relatively independent modules, but in assembly code, is not independent modules, in fact, they are achieved by jumping the corresponding function.
SWITCH:
SWITCH leave a pit here first....text:000000000040165F public SWITCH .text:000000000040165F SWITCH proc near ; CODE XREF: main+1C↑p .text:000000000040165F .text:000000000040165F var_8 = dword ptr -8 .text:000000000040165F var_4 = dword ptr -4 .text:000000000040165F .text:000000000040165F push rbp .text:0000000000401660 mov rbp, rsp .text:0000000000401663 sub rsp, 10h .text:0000000000401667 mov [rbp+var_8], 1 .text:000000000040166E mov eax, [rbp+var_8] .text:0000000000401671 cmp eax, 2 .text:0000000000401674 jz short loc_40167D .text:0000000000401676 cmp eax, 4 .text:0000000000401679 jz short loc_401686 .text:000000000040167B jmp short loc_40168F .text:000000000040167D ; --------------------------------------------------------------------------- .text:000000000040167D .text:000000000040167D loc_40167D: ; CODE XREF: SWITCH+15↑j .text:000000000040167D mov [rbp+var_4], 3 .text:0000000000401684 jmp short loc_401697 .text:0000000000401686 ; --------------------------------------------------------------------------- .text:0000000000401686 .text:0000000000401686 loc_401686: ; CODE XREF: SWITCH+1A↑j .text:0000000000401686 mov [rbp+var_4], 5 .text:000000000040168D jmp short loc_401697 .text:000000000040168F ; --------------------------------------------------------------------------- .text:000000000040168F .text:000000000040168F loc_40168F: ; CODE XREF: SWITCH+1C↑j .text:000000000040168F mov [rbp+var_8], 6 .text:0000000000401696 nop .text:0000000000401697 .text:0000000000401697 loc_401697: ; CODE XREF: SWITCH+25↑j .text:0000000000401697 ; SWITCH+2E↑j .text:0000000000401697 add [rbp+var_4], 1 .text:000000000040169B nop .text:000000000040169C add rsp, 10h .text:00000000004016A0 pop rbp .text:00000000004016A1 retn .text:00000000004016A1 SWITCH endp
(I don't know why, WHILE, FOR, SWITCH function names are normally displayed in assembly codes. For IF, it's not IF, but "sub_ [address]".