- 浏览: 2068796 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (1409)
- asp/asp.net学习 (241)
- oracle (10)
- delphi (295)
- java (27)
- pb (1)
- 每日点滴 (49)
- 学习方法 (40)
- 思想方面 (104)
- C语言 (5)
- C++ (1)
- 代码重构经验 (5)
- 软件工程 (3)
- 数据库 (99)
- 英语学习 (3)
- mysql (1)
- 该关注的网站或者网页 (42)
- 总结 (7)
- 要去做的事情 (33)
- 算法 (1)
- 网络方面 (29)
- 随感 (96)
- 操作系统 (36)
- UML (12)
- 常用工具的使用 (55)
- 脚本 (7)
- 汇编 (62)
- 数据结构 (2)
- 财务 (38)
- 语文作文 (16)
- 法律 (1)
- 股票 (88)
最新评论
-
devwang_com:
可以,学习了~~
列出文件夹下所有文件夹的树形结构--Dos命令 tree的使用 -
hvang1988:
不管用啊 frxrprt1.PreviewForm.Pare ...
fastReport预览时嵌入到别的窗体 -
00915132:
我也有这个疑问,非常 感 谢
left join加上where条件的困惑 --SQL优化 -
zhuyoulong:
学习了,高效读书
软件架构师要读的书 -
nTalgar:
非常感谢分享!
Application.ProcessMessages用法:
转自:http://bbs.pediy.com/showthread.php?t=89379
标 题: 【分享】从C语言到汇编,从汇编到C语言
作 者: wzjok
时 间: 2009-05-20,17:03
链 接: http://bbs.pediy.com/showthread.php?t=89379
要从事“逆向工程”工作,或对其感兴趣,请必然要接触到汇编语言。然而我们在对计算机语言的了解大都是从高级语言(如C、VB、Dephi)开始的。那当我们阅读由高级语言翻译成的机器语言时肯定会遇到很多障碍。下面是我在看了相关书籍后,做的一些笔记,希望有点参考价值!
一、循环语句与发汇编后的机器语言
1、for循环
下面是一段C语言的代码,我们的目的是来看其反汇编的结果:
int myfunction(int a,int b)
{
int c = a+b;
int i;
for(i=0;i<50;i++)
{
c = c+i;
}
return c;
}
前面的反汇编暂时不理它,这里从for的地方开始反汇编,结果如下:
for(i=0;i<50;i++)
00412BC7 mov dword ptr [i],0 // i=0; 给循环变量赋初值
00412BCE jmp myfunction+39h (412BD9h)// 跳到第一次循环处
> 00412BD0 mov eax,dword ptr [i]
| 00412BD3 add eax,1 // i++;修改循环变量
| 00412BD6 mov dword ptr [i],eax
| 00412BD9 cmp dword ptr [i],32h // 比较 i 与50的关系, 检查循环条件
| 00412BDD jge myfunction+4Ah (412BEAh) // 当 i>=50 [即 !(i<50) ] 时则跳出循环
| {
| c = c+i;
| 00412BDF mov eax,dword ptr [c] // 变量 c
| 00412BE2 add eax,dword ptr [i] // 变量 i
| 00412BE5 mov dword ptr [c],eax // c=c+i;
| }
< 00412BE8 jmp myfunction+30h (412BD0h) // 跳回去修改循环变量
00412BEA mov eax,dword ptr [c]
}
可以看到for循环主要用这么几条指令来实现:mov进行初始化。jmp跳过循环变量改变代码。cmp实现条件判断,jge根据条件跳转。
用jmp回到循环改变代码进行下一次循环。所以for结构有以下的显著特征:
mov <循环变量>,<初始值> ; 给循环变量赋初值
jmp B ;跳到第一次循环处
A: (改动循环变量) ;修改循环变量。
…
B: cmp <循环变量>,<限制变量> ;检查循环条件
jgp 跳出循环
(循环体)
…
jmp A ;跳回去修改循环变量
2、do循环
再看一下do循环,因为 do循环没有修改循环变量的部分,所以比for循环要简单一些。
do
{
c = c+i;
00411A55 mov eax,dword ptr [c]
00411A58 add eax,dword ptr [i]
00411A5B mov dword ptr [c],eax
} while(c< 100);
00411A5E cmp dword ptr [c],64h
00411A62 jl myfunction+35h (411A55h)
return c;
do循环就是一个简单的条件跳转回去。只有两条指令:
cmp <循环变量>,<限制变量>
jl <循环开始点>
3、while循环
while(c<100){
00411A55 cmp dword ptr [c],64h
00411A59 jge myfunction+46h (411A66h)
c = c+i;
00411A5B mov eax,dword ptr [c]
00411A5E add eax,dword ptr [i]
00411A61 mov dword ptr [c],eax
}
00411A64 jmp myfunction+35h (411A55h)
return c;
很明显,我们会发现while要更复杂一点。因为while除了开始的时候判断循环条件之外,后面还必须有一条无条件跳转回到循环开始的地方,共用三条指令实现:
A: cmp <循环变量>,<限制变量>
jge B
( 循环体)
…
jmp A
B: (循环结束了)
这样,我们对C语言中的循环结构的分析,就基本弄完了!当然,我们用同样的方法也可以分析出C语言在“分支语句”、以及其它的数据结构中的C代码与机器反汇编代码的关系了!
为了知识的完整性,这里补充一下C语言里的分支语句
二、分支语句
1、if-else 语句
为了观察其汇编语句,下面是一个简单的if判断结构:
if(a>0 && a<10)
{
printf("a>0");
}
else if( a>10 && a<100)
{
printf("a>10 && a<100");
}
else
{
printf("a>10 && a<100");
}
if 判断都是使用cmp再加上条件跳转指令。对于if( A && B)的情况,一般都是使用否决法。如果A不成立,立刻跳下一个分支。依次,如果 B 不成立,同样跳下一分支。
cmp 条件
jle 下一个分支
所以开始部分的反汇编为:
if(a>0 && a<10)
00411A66 cmp dword ptr [c],0
00411A6A jle 411A81h ; 跳下一个else if的判断点
00411A6C cmp dword ptr [c],0Ah
00411A70 jge 411A81h ; 跳下一个else if的判断点
{
printf("a>0");
00411A72 push offset string "a>0" (4240DCh)
00411A77 call @ILT+1300(_printf) (411519h)
00411A7C add esp,4
}
else if 的和 else 的特点是,开始都有一条无条件跳转到判断结束处,阻止前面的分支执行结束后,直接进入这个分支。这个分支能执行到的唯一途径只是,前面的判断条件不满足。
else 则在jmp之后直接执行操作。而else if则开始重复if之后的操作,用cmp比较,然后用条件跳转指令时行跳转。
else if( a>10 && a<100)
00411A7F jmp 411AA9h ;直接跳到判断块外
00411A81 cmp dword ptr [c],0Ah ;比较+条件跳转,目标为下一个分支处
00411A85 jle 411A9Ch
00411A87 cmp dword ptr [c],64h
00411A8B jge 411A9Ch
{
printf("a>10 && a<100");
00411A8D push offset string "a>10 && a<100" (424288h)
00411A92 call @ILT+1300(_printf) (411519h)
00411A97 add esp,4
}
else
00411A9A jmp 411AA9h ;这里是else,所以只有简单的一条跳转。
{
printf("a>10 && a<100");
00411A9C push offset string "a>10 && a<100" (424288h)
00411AA1 call @ILT+1300(_printf) (411519h)
00411AA6 add esp,4
}
return c;
2、switch-case 语句
switch 的特点是有多个判断。因为 swtich 显然不用判断大于小于,所以都是je(因此,C语言中switch语句不支持float类型的变量),分别跳到每个case处。最后一个是无条件跳转,直接跳到default处。以下的代码:
switch(a)
{
case 0:
printf("a>0");
case 1:
{
printf("a>10 && a<100");
break;
}
default:
printf("a>10 && a<100");
}
反汇编的switch(a)
00411A66 mov eax,dword ptr [a]
00411A69 mov dword ptr [ebp-0E8h],eax
00411A6F cmp dword ptr [ebp-0E8h],0 // case 0:
00411A76 je 411A83h
00411A78 cmp dword ptr [ebp-0E8h],1 // case 1:
00411A7F je 411A90h
00411A81 jmp 411A9Fh // default:
{
…
显然是比较a 是否是0、1这两个数字。汇编指令先把a移动到[ebp-0E8h]这个地址,然后再比较,这是调试版本编译的特点。可能是为了防止直接操作堆栈而导致堆栈破坏?最后一条直接跳转到default处。当然,如果没有default,就会跳到swtich{}之外。
从这里我们可以发现:switch语句里,完成“比较判断”的指令会与“case”指令的两部分,在汇编中,不是按照C语句逐句翻译的,而是分开为两个指令模块来实现的!
case 0:
printf("a>0");
00411A83 push offset string "a>0" (4240DCh)
00411A88 call @ILT+1300(_printf) (411519h)
00411A8D add esp,4
case 1:
{
printf("a>10 && a<100");
00411A90 push offset string "a>10 && a<100" (424288h)
00411A95 call @ILT+1300(_printf) (411519h)
00411A9A add esp,4
break;
00411A9D jmp myfunction+8Ch (411AACh)
}
default:
printf("a>10 && a<100");
00411A9F push offset string "a>10 && c<100" (424288h)
00411AA4 call @ILT+1300(_printf) (411519h)
00411AA9 add esp,4
}
至于case 和 default分支中,如果有break,则会增加一个无条件跳转汇编指令。若没有break,则就没有任何循环控制代码。
小结:如果在反汇编代码中发现连续多个“比较cmp”和“相等跳转je”就会让人联想到“switch”语句了!
发表评论
-
用汇编写的病毒代码
2010-05-29 08:04 1911转自:http://www.programfan.com ... -
堆和栈(堆栈)的区别
2010-05-20 16:47 873转自:http://www.360doc.com/sho ... -
OllyDBG 入门系列(三)-函数参考
2010-05-06 14:07 1401转自:http://bbs.pediy.com/s ... -
OllyDBG 入门系列(二)-字串参考
2010-05-05 19:02 1154转自:http://bbs.pediy.com/s ... -
用汇编编写DOS下的内存驻留程序(5)
2010-05-05 11:05 1033转自:http://www.x86asm.com/Dis ... -
用汇编编写DOS下的内存驻留程序(4)
2010-05-05 11:04 1176转自:http://www.x86asm.com/Displa ... -
用汇编编写DOS下的内存驻留程序(3)
2010-05-05 11:03 902转自:http://www.x86asm. ... -
用汇编编写DOS下的内存驻留程序(2)
2010-05-05 11:02 773转自:http://www.x86asm. ... -
用汇编编写DOS下的内存驻留程序(1)
2010-05-05 11:01 1511转自:http://www.x86 ... -
补码 左移与右移 32位系统
2010-05-02 11:04 2805QQ:797801 计算机中 ... -
c语言控制语句对应的汇编语句代码
2010-04-29 18:15 2263转:http://blog.csdn.net/ ... -
调试windows程序
2010-03-21 10:11 825debug 只能支持1M的寻址 如果需要调 ... -
ds:[bp+2]
2009-11-28 13:22 914mov ax,0 mov ds ... -
程序的起始地址的段地址
2009-11-26 09:38 1336生成EXE之后用Debug加载后,查看寄存器内容如下: ... -
将内存FFFF:0--FFFF:b单元中的数据复制到0:200--0:20b单元中
2009-10-25 21:13 1692该程序的功能: 将内存FFFF:0--FF ... -
标志寄存器
2009-10-25 18:46 1006方便记忆 OF 溢出(是/否) ... -
安全的一段内存空间 0:2000~0:02FF
2009-10-25 18:20 957看到120页了 我们要向内存里写东西 ... -
显示红心的汇编代码
2009-10-25 18:05 936assume cs:code code segment ... -
debug时 遇到loop 指令
2009-10-25 17:35 914debug时 遇到loop 指令 用 p指 ... -
Loop的使用
2009-10-23 21:06 1224看到107页了 王爽汇编第五章 Loop的使用 ...
相关推荐
《嵌入式软件基础:C语言与汇编的融合(翻译版)》以实践中最常运用的方式讲解汇编语言——实现小型、快速或特殊目的的例程,这些例程由主程序(高级语言编写,如C)调用。通过运用嵌入式软件环境,《嵌入式软件基础:...
C语言编译器会将源代码转换成汇编语言,然后再通过汇编器转换为机器码,这个过程使得C程序能够在多种不同的硬件平台上运行,这也是C语言被广泛用于操作系统、嵌入式系统以及各种软件开发的原因。 汇编语言是与特定...
"Keil 中 C 与汇编混合编程的方法" Keil 中 C 与汇编混合编程的方法是指在 Keil 环境中将 C 语言和汇编语言结合使用,以实现特定的编程目标。这种混合编程方式可以充分发挥 C 语言的高级编程能力和汇编语言的低级...
在"单片机C语言与汇编混编经典实例"中,你可能会学到如何定义汇编子程序并在C代码中调用,如何在C语言中使用汇编语句块(__asm__),以及如何在C代码中访问和修改硬件寄存器。这些实例将涵盖各种实际应用,包括...
### 单片机编程C语言与汇编比较 #### 1. C语言和汇编语言在开发单片机时各有哪些优缺点? - **汇编语言**: - **优点**: - **资源占用少**:由于汇编语言直接对应机器码,因此程序执行效率较高,特别适合资源...
3. C语言调用汇编代码:讨论C语言的函数调用约定,并展示如何在汇编代码中实现与C函数的接口。 4. 汇编代码调用C函数:说明如何在汇编程序中调用C函数,包括传递参数和返回值的机制。 5. 优化技巧:探讨如何通过...
当需要进行性能优化或者访问特定硬件功能时,程序员可能会选择将C语言与汇编语言混合使用。以下将详细探讨这个主题。 1. **C语言的优势与局限性** C语言的优点在于其抽象程度适中,它允许程序员高效地编写代码,...
在计数和加减运算上,C语言的`++`和`--`操作符在汇编中对应`inc`和`dec`指令。 在实际的单片机设计中,C语言和汇编语言的选择和结合取决于项目需求。C语言简化了程序设计,提高了开发效率,适合于处理复杂逻辑和...
### AVR中嵌入汇编 iar中C与汇编混合编程 #### 概述 本应用笔记阐述了如何在包括C语言和汇编代码的项目中设置并使用IAR C编译器来支持AVR控制器。通过混合使用C语言和汇编语言,设计者可以将强大的C语言指令与接近...
嵌入式软件基础:C语言与汇编的融合.pdf
1. C语言与汇编语言的基础:首先,读者需要了解两种语言的基本概念和语法,包括C语言的关键字、数据类型、流程控制语句以及汇编语言的指令集、寄存器使用等。 2. 混合编程环境设置:介绍如何配置开发环境,如选择...
- 在C语言程序中调用汇编程序时,由于汇编子程序与C语言主程序不在同一源文件中,因此汇编子程序被视为C程序的外部函数。 - 使用`extern`关键字声明汇编子程序,例如:`extern int my_asm_function(int param1, ...
C 语言与汇编语言混合编程 本实验主要介绍了 ARM 嵌入式 C 语言编程的基本方法、嵌入式汇编(Inline Assembly)编程规则和方法,以及汇编语言程序和 C 语言程序之间的相互调用规则和编程方法。 一、ARM 嵌入式 C ...
总结来说,CCS集成开发环境下的C与汇编的混合编程实现,要求开发者必须对C语言和汇编语言都有较好的掌握,同时还需要了解目标硬件平台的指令集和特性。通过合理选择编程语言和编写高效的混合代码,可以在DSP开发中...
4. **C语言与汇编的接口**:在嵌入式编程中,开发者常常需要在C程序中插入汇编代码段,以实现特定功能或优化关键部分。这种混合编程要求对两种语言都有深入理解。 5. **调用约定**:当C语言调用汇编函数或反之时,...
【C语言与汇编语言混合编程的实现】 在嵌入式系统开发中,尤其是在单片机编程中,C语言和汇编语言的混合编程是一种常见的技术。C语言因其高级抽象和良好的可移植性而受到广泛欢迎,而汇编语言则能提供对底层硬件的...
《嵌入式软件基础:C语言与汇编的融合》是一本专为嵌入式系统开发者设计的基础教程,由国际知名专家编著。本书旨在帮助读者深入理解嵌入式开发的核心概念,通过C语言和汇编语言的结合,提升开发者的编程技能和底层...
为了更好地理解和实践C语言与汇编语言的混合编程方法,研究者们分析了TurboC与汇编语言的混合编程应用方法,并提供了具体的实例,以方便C语言开发人员掌握这种方法。 最后,由于本文档是研究性质的文献,因此研究者...
在本例中,我们关注的是C语言与汇编语言的混合编程,这通常发生在需要高效性能或者直接控制硬件操作的情况下。下面将详细探讨这个主题。 首先,C语言是一种高级编程语言,以其简洁、通用和接近机器代码的特性而闻名...
嵌入式软件基础C语言与汇编的融合,是学习嵌入式的必要之书