您的位置:首页 > 编程语言 > C语言/C++

[汇编学习笔记]if/else,while,for,switch in Assembly Language

2017-10-29 11:20 429 查看
写了一段C代码,包含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++;
}


编译之后, 用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              endp
while在汇编码中,是先跳转到一个较后的位置,然后执行条件判断,满足则往回跳,顺序执行一些东西后,就又到了条件判断的地方。直到不满足条件了,就不往回跳,顺序执行了。

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             endp
for循环在汇编码中,其实和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_[地址] ")
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  汇编 c语言
相关文章推荐