如何理解如下代码中的地址表达式(代码不长)
时间:2011-03-13
来源:互联网
很久以前学习过16位汇编语言,对32位汇编只是稍微有些了解.最近调试一段VC写的代码中遇到如下一个函数的汇编代码,但是我不知道怎么去理解里面的地址表达试,代码不长,那位兄弟有空就请帮忙解释一下,谢谢了
原始的VC函数如下
C/C++ code
在VC调试器的反汇编窗口中的代码如下:
C/C++ code
我把代码复制到别的地方后反汇编代码如下:
Assembly code
这个函数我打算用来创建远线程的,最终会在其它进程里执行。
先不管以上代码是否会正常工作,我的问题是:
如这行代码怎么看
call dword ptr ds:[44E308h]
我如何去计算其线性地址?
记得以前16位汇编里,应该是ds*16+44E308h吧(当然16位里不能这么大的数)。后来我一直以为32位里就是直接取44E308h这个值,因为我一直以为ds的值应该为0,所以不必去管32位CPU到底用什么方法取得线性地址。但是现在我发现在调试的时候我的段寄存器竟然不是0,而是如下的值:
EAX = 00BBB680
EBX = 00418570
ECX = 00000000
EDX = 00001000
ESI = 00418970
EDI = 00BBBA80
EIP = 00413391
ESP = 0012F4F0
EBP = 0012F514
EFL = 00000202
CS = 001B
DS = 0023
ES = 0023
SS = 0023
FS = 003B
GS = 0000
那么我觉得自己以前的知识彻底的错了,真是郁闷啊,我也不知道以前是从哪里获得的认识:32位段寄存器为0.
以上都是废话,只是想说明下我为什么需要汇编知识,大家可以直接跳过,还是来继续我问的问题:
当DS = 0023h时指令call dword ptr ds:[44E308h]里的线性地址是多少,是怎么计算的?
另我使用的操作系统是Windows 2003企业版,CPU是AMD 4核,内存8G
原始的VC函数如下
C/C++ code
DWORD WINAPI RemoteThread(void*p) { DWORD d=(DWORD)::GetProcAddress(::GetModuleHandle(0),"RemoteThread"); return d; }
在VC调试器的反汇编窗口中的代码如下:
C/C++ code
DWORD WINAPI RemoteThread(void*p) { DWORD d=(DWORD)::GetProcAddress(::GetModuleHandle(0),"RemoteThread"); 00418570 push offset string "RemoteThread" (48B6D8h) 00418575 push 0 00418577 call dword ptr [__imp__GetModuleHandleW@4 (44E308h)] 0041857D push eax 0041857E call dword ptr [__imp__GetProcAddress@8 (44E304h)] return d; } 00418584 ret 4
我把代码复制到别的地方后反汇编代码如下:
Assembly code
00BBB680 push 48B6D8h 00BBB685 push 0 00BBB687 call dword ptr ds:[44E308h] ;这个地址式如何去确定其线性地址? 00BBB68D push eax 00BBB68E call dword ptr ds:[44E304h] 00BBB694 ret 4
这个函数我打算用来创建远线程的,最终会在其它进程里执行。
先不管以上代码是否会正常工作,我的问题是:
如这行代码怎么看
call dword ptr ds:[44E308h]
我如何去计算其线性地址?
记得以前16位汇编里,应该是ds*16+44E308h吧(当然16位里不能这么大的数)。后来我一直以为32位里就是直接取44E308h这个值,因为我一直以为ds的值应该为0,所以不必去管32位CPU到底用什么方法取得线性地址。但是现在我发现在调试的时候我的段寄存器竟然不是0,而是如下的值:
EAX = 00BBB680
EBX = 00418570
ECX = 00000000
EDX = 00001000
ESI = 00418970
EDI = 00BBBA80
EIP = 00413391
ESP = 0012F4F0
EBP = 0012F514
EFL = 00000202
CS = 001B
DS = 0023
ES = 0023
SS = 0023
FS = 003B
GS = 0000
那么我觉得自己以前的知识彻底的错了,真是郁闷啊,我也不知道以前是从哪里获得的认识:32位段寄存器为0.
以上都是废话,只是想说明下我为什么需要汇编知识,大家可以直接跳过,还是来继续我问的问题:
当DS = 0023h时指令call dword ptr ds:[44E308h]里的线性地址是多少,是怎么计算的?
另我使用的操作系统是Windows 2003企业版,CPU是AMD 4核,内存8G
作者: liuhua1982 发布时间: 2011-03-13
ds的值是段选择子,对应着全局描述符表或局部描述符表中的一个段描述符,段描述符中有段基址,修改ds时从新的段选择子对应的段描述符中取得段基址,放在ds的缓存寄存器中
call dword ptr ds:[44E308h]从ds的缓存寄存器中获得段基址,加上段偏移即得线性地址
windows中ds,ss,cs,es的段基址为0
call dword ptr ds:[44E308h]从ds的缓存寄存器中获得段基址,加上段偏移即得线性地址
windows中ds,ss,cs,es的段基址为0
作者: Lactoferrin 发布时间: 2011-03-13
32位windows中ds,ss,cs,es的段基址被设置为0
x64中ds,ss,cs,es的段基址直接被忽略掉
x64中ds,ss,cs,es的段基址直接被忽略掉
作者: Lactoferrin 发布时间: 2011-03-13
原来段寄存器里只是存储着"全局描述符表或局部描述符表"中的一条记录的..(地址?索引?当然这个问题我自己再去找资料,以前课本早不到了,如果谁有资料欢迎给个网页地址)。
既然windows中ds,ss,cs,es的段基址为0那么我以前理解的段积存器为0其实也是歪打正着了,难怪以前在VC中嵌入一些小段的汇编代码也没出什么问题。
感谢Lactoferrin
既然windows中ds,ss,cs,es的段基址为0那么我以前理解的段积存器为0其实也是歪打正着了,难怪以前在VC中嵌入一些小段的汇编代码也没出什么问题。
感谢Lactoferrin
作者: liuhua1982 发布时间: 2011-03-13
段选择子中有描述符表的索引,intel的开发人员手册里有说明
作者: Lactoferrin 发布时间: 2011-03-13
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28