关于C++: try...catch...的汇编实现

wonaixiaogang 2009-05-18 10:34:40

//这里是C++的源码
#include "stdafx.h"
void main()
{
int i;
try
{
i=0;
i++;
}
catch(...)
{
i++;
}
}


;这里是VC2008 输出的反汇编源码
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08

TITLE d:\VC++应用程序\test\test\test\test.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC _main
EXTRN ___security_cookie:DWORD
EXTRN ___CxxFrameHandler3:PROC
EXTRN @__security_check_cookie@4:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __RTC_InitBase:PROC
; COMDAT xdata$x
; File d:\vc++应用程序\test\test\test\test.cpp
xdata$x SEGMENT
__catchsym$_main$2 DD 040H
DD 00H
DD 00H
DD FLAT:__catch$_main$0
__unwindtable$_main DD 0ffffffffH
DD 00H
DD 0ffffffffH
DD 00H
__tryblocktable$_main DD 00H
DD 00H
DD 01H
DD 01H
DD FLAT:__catchsym$_main$2
__ehfuncinfo$_main DD 019930522H
DD 02H
DD FLAT:__unwindtable$_main
DD 01H
DD FLAT:__tryblocktable$_main
DD 2 DUP(00H)
DD 00H
DD 01H
xdata$x ENDS
; COMDAT rtc$TMZ
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
; Function compile flags: /Odtp /RTCsu /ZI
rtc$IMZ ENDS
; COMDAT _main
_TEXT SEGMENT
_i$ = -24 ; size = 4
__$EHRec$ = -16 ; size = 16
_main PROC ; COMDAT

; 7 : {

push ebp
mov ebp, esp
push -1
push __ehhandler$_main
mov eax, DWORD PTR fs:0
push eax
push ecx
sub esp, 204 ; 000000ccH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-220]
mov ecx, 51 ; 00000033H
mov eax, -858993460 ; ccccccccH
rep stosd
mov eax, DWORD PTR ___security_cookie
xor eax, ebp
push eax
lea eax, DWORD PTR __$EHRec$[ebp+4]
mov DWORD PTR fs:0, eax
mov DWORD PTR __$EHRec$[ebp], esp

; 8 : int i;
; 9 : try
; 10 : {

mov DWORD PTR __$EHRec$[ebp+12], 0

; 11 : i=0;

mov DWORD PTR _i$[ebp], 0

; 12 : i++;

mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax

; 13 : }

jmp SHORT $LN4@main
__catch$_main$0:

; 14 : catch(...)
; 15 : {
; 16 : i++;

mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax

; 17 : }

mov DWORD PTR __$EHRec$[ebp+12], -1
mov eax, $LN2@main
ret 0
$LN4@main:
mov DWORD PTR __$EHRec$[ebp+12], -1
$LN2@main:

; 18 : }

xor eax, eax
mov ecx, DWORD PTR __$EHRec$[ebp+4]
mov DWORD PTR fs:0, ecx
pop ecx
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
_TEXT ENDS
; COMDAT text$x
text$x SEGMENT
__ehhandler$_main:
mov edx, DWORD PTR [esp+8]
lea eax, DWORD PTR [edx+12]
mov ecx, DWORD PTR [edx-224]
xor ecx, eax
call @__security_check_cookie@4
mov eax, OFFSET __ehfuncinfo$_main
jmp ___CxxFrameHandler3
text$x ENDS
_main ENDP
END

求汇编源码每一行的详细解释,谢谢!!!!
...全文
892 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
amethystsnow 2009-09-28
  • 打赏
  • 举报
回复
DDK里的macro就有_TRY,,何必每次都自己...
三分001 2009-09-18
  • 打赏
  • 举报
回复
张口就是:
[Quote=引用楼主 wonaixiaogang 的回复:]

求汇编源码每一行的详细解释,谢谢!!!!

[/Quote]

楼主真够无耻的.
gp341 2009-08-26
  • 打赏
  • 举报
回复
看罗云斌的书里介绍的很详细
大熊猫侯佩 2009-08-21
  • 打赏
  • 举报
回复
seh包装,注意fs的读写
土豆 2009-08-21
  • 打赏
  • 举报
回复
顶一个
DarkChampion 2009-08-21
  • 打赏
  • 举报
回复
mark
gzgzlxg 2009-08-21
  • 打赏
  • 举报
回复
直接使用LIBC.LIB中的vc++的初始化函数。
回帖是一种美德。
  • 打赏
  • 举报
回复
汇编啊,汇编
wlg_linux 2009-08-18
  • 打赏
  • 举报
回复
#include "stdafx.h"
void main()
{
int i;
try
{
i=0;
i++;
}
catch(...)
{
i++;
}
}
在Linux平台上只需要执行命令gcc -S file.cpp就可以得到它的汇编形式。
Michael_g 2009-05-26
  • 打赏
  • 举报
回复
返回值说明:
错误处理函数的返回值只有两个。
EXCEPTION_CONTINUE_SEARCH = 1 不处理异常,转交系统处理
EXCEPTION_CONTINUE_EXECUTION = 0 修复错误,从异常发生处继续执行

其它关于 错误处理函数参数的信息参看 http://tieba.baidu.com/f?kw=waruqi 里的《SEH结构化异常处理》
Michael_g 2009-05-26
  • 打赏
  • 举报
回复
SEH 异常原理:
在 Windows 下,fs:[0] 指向一个SEH 数据结构,当发生异时,系统会调用 SEH结构指向的错误处理函数,所以我们中要改变 fs:[0]里的内容就行了。原理如下:
SEH结构:
{
DWORD NextSEH; 下个SEH结构
DWORD ErrProc; 错误处理函数
}
实现方法如下:

push Error_Handler ;压入错误处理函数地址
push fs:[0] ; 压入当SEH结构地址
mvo fs:[0],esp ;更新 SEH 链表,使其指向你的SEH

xor eax,eax
mov eax,dword ptr [eax];产生异常

...
...

恢复原SEH链表
pop dword ptr fs:[0]
pop eax



错误处理函数定义
Error_Handler proc uses ecx lpExceptRecord:DWORD, lpFrame:DWORD, lpContext:DWORD, lpDispatch:DWORD
...
...

ret
Error_Handler endp
Areslee 2009-05-25
  • 打赏
  • 举报
回复
try/throw/catch和SEH不同的
xiaopoy 2009-05-25
  • 打赏
  • 举报
回复
try/throw/catch在win下是包装的seh,正是LZ想知道的,不然问的该是c++的try/throw/catch如何实现。

   TITLE    d:\VC++应用程序\test\test\test\test.cpp
.686P
.XMM
include listing.inc
.model flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC _main
EXTRN ___security_cookie:DWORD
EXTRN ___CxxFrameHandler3:PROC
EXTRN @__security_check_cookie@4:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __RTC_InitBase:PROC
; COMDAT xdata$x
; File d:\vc++应用程序\test\test\test\test.cpp

此段类似于c.h文件,定义个样子。包括了目标object所用的指令系和内存模式,导入的头文件和库,导出的函数。

_i$ = -24                        ; size = 4
__$EHRec$ = -16 ; size = 16

全局变量定义

_main    PROC                        ; COMDAT

; 7 : {

push ebp
mov ebp, esp//保护上级函数的参数
push -1
push __ehhandler$_main
mov eax, DWORD PTR fs:0
push eax
push ecx
sub esp, 204 ; 000000ccH //划分要用的堆栈
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-220] // rep stosd,把edi指向的ecx*4字节的数据覆盖为eax.
//即将自己堆栈初始化为0xcccccccc,这特色的数字在溢出时有助于定位溢出code
mov ecx, 51 ; 00000033H
mov eax, -858993460 ; ccccccccH
rep stosd
mov eax, DWORD PTR ___security_cookie //cookie为vc带/GS保护堆栈参数时的产品。
//意为, 在缓冲区和返回地址间的"缓冲带"
//发生溢出则cookie会首先被覆盖,在函数结束调用返回地址前检查cookie若错误则已溢出停止执行,便阻止了对溢
//出的利用
xor eax, ebp
push eax
lea eax, DWORD PTR __$EHRec$[ebp+4] //初始化SEH结构
mov DWORD PTR fs:0, eax //fs:0为ETHREAD 结构,fs:[0]为当前函数的SEH结构指针
mov DWORD PTR __$EHRec$[ebp], esp//此处的__$EHRec$为__ehhandler$_main的别名
mov DWORD PTR __$EHRec$[ebp+12], 0
; 8 : int i; //所的对应c++code
; 9 : try
; 10 : {




; 11   :         i=0;

mov DWORD PTR _i$[ebp], 0

; 12 : i++;

mov eax, DWORD PTR _i$[ebp]
add eax, 1
mov DWORD PTR _i$[ebp], eax

i= 0;
i= i+1;
i= i;

; 13   :     }
jmp SHORT $LN4@main

执行至函数解释未出错则直接运行退出函数code

$LN4@main:
mov DWORD PTR __$EHRec$[ebp+12], -1
$LN2@main:

; 18 : }

xor eax, eax
mov ecx, DWORD PTR __$EHRec$[ebp+4] //恢复FS:0为上个函数的SEH结构
mov DWORD PTR fs:0, ecx
pop ecx
pop edi
pop esi
pop ebx
mov esp, ebp //整理堆栈。抛弃本函数的堆栈
pop ebp
ret 0 //返回上层函数
_TEXT ENDS
; COMDAT text$x
text$x SEGMENT



__catch$_main$0:

; 14 : catch(...)
; 15 : {
; 16 : i++;

mov eax, DWORD PTR _i$[ebp] //捕获到异常后执行 i= i+1; i= i;
add eax, 1
mov DWORD PTR _i$[ebp], eax

; 17 : }

mov DWORD PTR __$EHRec$[ebp+12], -1//置空本函数SEH callback的指针
mov eax, $LN2@main//返回给运行时库 下一步要执行的code
ret 0

catch为一个被运行时库调用的callback

__ehhandler$_main:
mov edx, DWORD PTR [esp+8]
lea eax, DWORD PTR [edx+12]
mov ecx, DWORD PTR [edx-224]
xor ecx, eax
call @__security_check_cookie@4
mov eax, OFFSET __ehfuncinfo$_main
jmp ___CxxFrameHandler3
text$x ENDS
_main ENDP
END

c++默认的异常处理流程:
检查cookie并在溢出时处理。不做任何异常的修复,直接反馈给上层SEH
huofen2005 2009-05-21
  • 打赏
  • 举报
回复
不会,帮顶!
VC6的代码反汇编下44看。
。Net代码复杂化了
cnzdgs 2009-05-18
  • 打赏
  • 举报
回复
内容概要:本文针对无刷直流电机驱动的电子机械制动(EMB)执行器,建立了考虑Stribeck摩擦特性的非线性耦合动力学模型,并在Simulink环境中完成了系统级仿真分析。研究综合集成了电机动力学、齿轮传动机构与制动执行机构的动力学特性,构建了高保真的机电一体化系统模型。重点引入Stribeck摩擦模型以精确描述低速工况下执行器内部存在的静摩擦、粘滞摩擦与库仑摩擦之间的过渡行为,有效提升了系统在启停、反向运动等瞬态过程中的动态响应仿真精度。通过多工况仿真验证了模型的有效性,能够准确反映摩擦引起的爬行、滞后与定位误差等非线性现象,为EMB系统的高性能控制算法设计(如摩擦补偿、滑模控制)与结构优化提供了高可信度的仿真平台。; 适合人群:从事汽车电子制动系统、电机驱动控制、机电系统建模与仿真研究的研究生、科研人员及工程技术人员,需具备扎实的机械动力学、自动控制理论基础和MATLAB/Simulink仿真能力。; 使用场景及目标:①用于高精度电子机械制动系统的设计验证与性能预测;②为消除摩擦非线性影响的先进控制策略(如自适应控制、智能控制)提供精确的被控对象模型;③深入探究Stribeck摩擦等非线性因素对系统动态性能(如响应延迟、稳态误差)的作用机理; 阅读建议:读者应结合提供的Simulink模型文件,深入剖析Stribeck摩擦模块的数学实现与参数辨识方法,建议通过改变输入指令(如阶跃、正弦)和负载条件进行对比仿真,以直观理解非线性摩擦对系统动态特性的影响。

21,500

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧