[汇编学习笔记]if/else,while,for,switch in Assembly Language
2017-10-29 11:20
429 查看
写了一段C代码,包含if/else, while ,for ,switch:
编译之后, 用IDA得到汇编码:
IF:
WHILE:
FOR:
另外的感想:在C中,有两个 i 变量,一个的作用域是整个函数,另一个的作用域只是内层块。但是在汇编码中,只是把它们看成了两个不同的变量,除此之外没有区别——可以说,这两个变量的作用域都是整个函数。在汇编码中,似乎并不存在“内层块”这种东西。if/else,while,for中的代码,尽管在C中,看起来都是相对独立的模块,但是在汇编码中,并不是独立的模块,其实都是通过跳转实现相应功能的。
SWITCH:
在switch的条件判断中,没有直接比较[rbp+var_8]和case的数字,而是先把[rbp+var_8]的值传给了eax寄存器。之后用eax进行比较。
另外,到此,可以看到switch进行条件判断,与if进行条件判断的不同之处:尽管要判断的都是一个变量是否等于某数,if 用的是 jnz,非零跳转,跳转到 else 的部分;
而 switch用的是 jz 为零则跳转,跳转到相应 case 后的部分。
而default部分,尽管在C中,default部分结束后,有个反花括号,但是在汇编码中,它是直接和后面的部分连在一起的。这再次印证了上面说的,汇编码中不像C那样,它“没有内层块”。
最后(不知道为什么,WHILE, FOR, SWITCH的函数名在汇编码中都是正常显示的,就IF, 显示的不是IF, 而是 " sub_[地址] ")
#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++; }
编译之后, 用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]减二 .text:00000000004015EF jnz short loc_4015F7 ;非零,则跳转到loc_4015E7 .text:00000000004015F1 add [rbp+var_4], 1 ;[rbp+var_4]加一 .text:00000000004015F5 jmp short loc_4015FB ;跳转到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
WHILE:
.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]减二 .text:000000000040161B jnz short loc_401613 ;非零,则跳转到loc_401613 .text:000000000040161D nop .text:000000000040161E add rsp, 10h .text:0000000000401622 pop rbp .text:0000000000401623 retn .text:0000000000401623 WHILE endpwhile在汇编码中,是先跳转到一个较后的位置,然后执行条件判断,满足则往回跳,顺序执行一些东西后,就又到了条件判断的地方。直到不满足条件了,就不往回跳,顺序执行了。
FOR:
.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 endpfor循环在汇编码中,其实和while循环是差不多的。
另外的感想:在C中,有两个 i 变量,一个的作用域是整个函数,另一个的作用域只是内层块。但是在汇编码中,只是把它们看成了两个不同的变量,除此之外没有区别——可以说,这两个变量的作用域都是整个函数。在汇编码中,似乎并不存在“内层块”这种东西。if/else,while,for中的代码,尽管在C中,看起来都是相对独立的模块,但是在汇编码中,并不是独立的模块,其实都是通过跳转实现相应功能的。
SWITCH:
.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
在switch的条件判断中,没有直接比较[rbp+var_8]和case的数字,而是先把[rbp+var_8]的值传给了eax寄存器。之后用eax进行比较。
另外,到此,可以看到switch进行条件判断,与if进行条件判断的不同之处:尽管要判断的都是一个变量是否等于某数,if 用的是 jnz,非零跳转,跳转到 else 的部分;
而 switch用的是 jz 为零则跳转,跳转到相应 case 后的部分。
而default部分,尽管在C中,default部分结束后,有个反花括号,但是在汇编码中,它是直接和后面的部分连在一起的。这再次印证了上面说的,汇编码中不像C那样,它“没有内层块”。
最后(不知道为什么,WHILE, FOR, SWITCH的函数名在汇编码中都是正常显示的,就IF, 显示的不是IF, 而是 " sub_[地址] ")
相关文章推荐
- 【Swift】学习笔记(五)——控制语句(if,switch,for-in,for,while,do-while)
- Swift第三课 分支语句 if else for forin switch while do-while
- 每天学习一算法系列(12) (求1+2+…+n,不能使用乘除法,for、while、if 、else、switch、case 等关键字以及条件判断语句)
- C++ Primer 学习笔记_19_语句 --if/switch/while/for语句
- C/C++学习(一)题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
- c++学习 day2 循环学习(while do while for) 分支学习(if ; if else; if else if; switch的应用 )
- Javascript:基本语句(if-else/switch/for/while/for-in/try-catch)
- 求 1+2+...+n, 要求不能使用乘除法、for、while、if、else、switch、case 等关键字以及条件判断语句 (A?B:C)。
- 计算1-n的和(不用for, while, goto, if, else, switch, case和三目运算符, 也不用乘除法)---利用pow函数
- 求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)
- linux shell编程控制结构:expr、let、for、while、until、shift、if、case、break、continue、函数、select 学习笔记
- 【练习】题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case 等关键字以及条件判断语句
- Go语言学习笔记 --- 控制语句之if判断,循环语句for, switch语句和跳转语句
- 求1+2+3+...+n,要求不能使用乘除法,for,while,if,else,switch,case等关键字以及条件判断语句
- 题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
- 题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)
- 3、C语言流程控制 if...else、switch、for、while、do while
- JAVA学习笔记4——if语句+switch语句+while语句
- 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
- 计算1-n的和(不用for, while, goto, if, else, switch, case和三目运算符, 也不用乘除法)---利用多态性