首页
社区
课程
招聘
寄存器的常用含义还有那些?
发表于: 2006-7-28 22:22 5974

寄存器的常用含义还有那些?

2006-7-28 22:22
5974
在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX用于记数等等
  在win32的环境下EBP寄存器用与存放在进入call以后的ESP的值,便于退出的时候回复ESP的值,达到堆栈平衡的目的。
那么,EDX,EBX,ESP,ESI,EDI的常用功能是什么呢?

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
2
一般说来在优化版的C++里面  寄存器都回同等对待
2006-7-28 22:40
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
用起来是可以等同看待的
不过习惯用法总是有的,象上面说的那样
2006-7-29 00:09
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
4
16位汇编 或许说手写汇编确实是
并且CPU也对这些指令作了一些优化。
问题是。现在几个人在用纯汇编。。所以这些意义上不大
规则倒是有一些 但是实规则不是习惯, 详细查MSDN
比如EAX放返回值 是必须,而不是习惯 。
比如Fastcall ecx edx 放参数
thiscall ecx放指针
这些都是标准规定的 而所说的ecx习惯上作为循环计数器 这种应该说很少看到,虽然有些指令比如Rep是看Cx但是编译器都会在要执行这个指令之前的最多几行内才把数据存到ECX,
C++编译器高度优化,他会将寄存器最大化利用,这种方式在循环中效果非常明显
但你说的ESP指针,在VC8里面 如果钩选了Inline和省略ESP指针 这些几乎看不到,
你看到的WINAPI 这些第一是在早期版本的VC中生成的,
2.WINAPI是稳定压倒一切,不一定要速度最大化,
所以说往往WINAPI你传递空指针也不容易异常就是这个原因,
里面对指针检查很严格
因为省略EBP指针以后虽然可以多用一个寄存器 但是必须保证ESP不能够和预订的代码有一点差距否则代码就全部出错者在WINDOWS中是不允许的,所以说你看VC7开始 都基本上默认ESP检查在每一个外部函数调用以后。

最后说一句 我们多数是在和编译器打交道,真正看程序员的汇编代码时非常非常少的 。
不要过分记住这些,多实践一下自然就知道了

如果你把这些所谓的常用含义拿去看优化编译器的化,你会觉得和预想的相差太大了
2006-7-29 00:59
0
雪    币: 208
活跃值: (55)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
我个人觉得“在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别”这句话有99%的误导成分。

每个寄存器只是用做储存时才没有区别,但寄存器的主要作用并不是存储,而是作为实现cpu动作的载体,绝大部分cpu指令都有它特定使用的寄存器,所以寄存器的所谓“习惯使用”是为了配合cpu的,不是真正的主观习惯。

最迷惑的就是AX,BX,CX,DX这几个寄存器的名字,初学时以为就是ABCDEFG等等,其实并不这样。A代表累加(accumulator),B代表基址(base),C代表计数(count),D代表数据(data)。而它们各有各的作用。比如清零一段内存,最好的方法就是将eax置0,ecx放次数,edi放目标首地址,然后stos(b/w/d)。这些根本就是特性而不是习惯。至于返回值放eax,那除了是约定以外,还更是因为80x86针对操作eax的指令做了优化,尽量地使用eax可以提高程序的效率。比如
add eax, 100的指令码为05 00 01 00 00
add ebx, 100的指令码为81 C3 00 01 00 00
用eax就省出1字节了。

而esp作为栈顶指针,更是不能不服从的,因为push和pop用的一定是esp。esi和edi因为串处理指令的缘故而用在源数据指针和目的数据指针。

因此这些所谓的习惯都是缘由自cpu的指令,楼主接触汇编指令多了以后,自然而然也会被迫“养成习惯”的了^_^
2006-7-29 01:11
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
6
最好的方法就是将eax置0,ecx放次数,edi放目标首地址,然后stos(b/w/d)。

你看过目前的C语言编译器有这句话嘛?
不要忘记了80386以后CPU执行简单指令会比执行复杂指令快的多

好比说目前的P4内部有三个简单解码器  而只有一个复杂解码器
这也是为什么编译器很多时候不用直接出发要转换为一些Shl指令的原因

另外执行速度主要不是看字节的长度

而现在的及其哪个不是XXXmB++ 那几个字节已经不是追求的目标了
所以说你看 INTER优化版编译器 有一个LOOP展开
就是花内存来换取速度
2006-7-29 01:25
0
雪    币: 208
活跃值: (55)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
rep stos:
ecx=0时,6时钟周期
ecx>0时,9+ecx时钟周期
我菜,还没有想出更快或更节省空间的方法,愿闻其详。

除法用shl(应该是shr吧),也只是除数是2的次方时才能用。除一个素数怎么shx。而且,这个问题跟寄存器的使用习惯没什么关系吧。

速度一定、使用同样方便的情况下,为什么不减少体积?API被调用N多次,这样省出的空间不少啊!即使再有空,也没人宁愿推着车子回家也不开着车回家吧,除法没油或车坏了。

(最后展开loop的,很想知道原因。瞎猜一下,是不是因为要用到太多的寄存器,或者循环过程中ecx还有其他用途,而不想重复push/pop,所以才展开呢 猜猜而已,
不好意思,把楼上的“loop”理解错了。急急找intel compiler的文档看了一下,暂时感觉这个问题跟寄存器的使用也没有关系。
2006-7-29 02:39
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
8
。。。这种东西也没有必要争论  个人有个人的理解。

总之恕我直言:

如果你觉得INTER C++ 9.1编译器 开发CPU的厂家 没有你对所谓‘时钟周期’的理解理解的多得话,那我也没有办法。

CPU不要想得太简单了。

速度的决定因素不是只取决于时钟周期。个人理解而已,技术交流哈。
2006-7-29 04:24
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
9
00401024  mov         ecx,19h
00401029  lea         esi,[esp+10h]
0040102D  lea         edi,[esp+74h]
00401031  rep movs    dword ptr es:[edi],dword ptr [esi]
复制100字节
复制100个字节
INTER编译器
        memcpy(str2,str1,100);
00401025  mov         eax,dword ptr [str1]
00401028  mov         dword ptr [str2],eax
0040102B  mov         edx,dword ptr [ebp-14h]
0040102E  mov         dword ptr [ebp-8],edx
00401031  mov         ecx,dword ptr [ebp-10h]
00401034  mov         dword ptr [ebp-4],ecx
00401037  mov         eax,dword ptr [str2]
0040103A  mov         dword ptr [ebp],eax
0040103D  mov         eax,dword ptr [ebp-8]
00401040  mov         dword ptr [ebp+4],eax
00401043  mov         eax,dword ptr [ebp-4]
00401046  mov         dword ptr [ebp+8],eax
00401049  mov         eax,dword ptr [ebp]
0040104C  mov         dword ptr [ebp+0Ch],eax
0040104F  mov         eax,dword ptr [ebp+4]
00401052  mov         dword ptr [ebp+10h],eax
00401055  mov         eax,dword ptr [ebp+8]
00401058  mov         dword ptr [ebp+14h],eax
0040105B  mov         eax,dword ptr [ebp+0Ch]
0040105E  mov         dword ptr [ebp+18h],eax
00401061  mov         eax,dword ptr [ebp+10h]
00401064  mov         dword ptr [ebp+1Ch],eax
00401067  mov         eax,dword ptr [ebp+14h]
0040106A  mov         dword ptr [ebp+20h],eax
0040106D  mov         eax,dword ptr [ebp+18h]
00401070  mov         dword ptr [ebp+24h],eax
00401073  mov         eax,dword ptr [ebp+1Ch]
00401076  mov         dword ptr [ebp+28h],eax
00401079  mov         eax,dword ptr [ebp+20h]
0040107C  mov         dword ptr [ebp+2Ch],eax
0040107F  mov         eax,dword ptr [ebp+24h]
00401082  mov         dword ptr [ebp+30h],eax
00401085  mov         eax,dword ptr [ebp+28h]
00401088  mov         dword ptr [ebp+34h],eax
0040108B  mov         eax,dword ptr [ebp+2Ch]
0040108E  mov         dword ptr [ebp+38h],eax
00401091  mov         eax,dword ptr [ebp+30h]
00401094  mov         dword ptr [ebp+3Ch],eax
00401097  mov         eax,dword ptr [ebp+34h]
0040109A  mov         dword ptr [ebp+40h],eax
0040109D  mov         eax,dword ptr [ebp+38h]
004010A0  mov         dword ptr [ebp+44h],eax
004010A3  mov         eax,dword ptr [ebp+3Ch]
004010A6  mov         dword ptr [ebp+48h],eax
004010A9  mov         eax,dword ptr [ebp+40h]
004010AC  mov         dword ptr [ebp+4Ch],eax
004010AF  mov         eax,dword ptr [ebp+44h]
004010B2  mov         dword ptr [ebp+50h],eax
004010B5  mov         eax,dword ptr [ebp+48h]
004010B8  mov         dword ptr [ebp+54h],eax
1000字节 P4优化
004021C0  sub         ecx,20h
004021C3  movdqa      xmm3,xmmword ptr [esi+10h]
004021C8  movdqa      xmm0,xmmword ptr [esi+20h]
004021CD  add         esi,20h
004021D0  psrldq      xmm1,8
004021D5  movdqa      xmm2,xmm3
004021D9  pslldq      xmm3,8
004021DE  por         xmm3,xmm1
004021E2  psrldq      xmm2,8
004021E7  movdqa      xmm1,xmm0
004021EB  pslldq      xmm0,8
004021F0  por         xmm0,xmm2
004021F4  movdqa      xmmword ptr [edx],xmm3
004021F8  movdqa      xmmword ptr [edx+10h],xmm0
004021FD  add         edx,20h
00402200  cmp         ecx,20h
00402203  jge         004021C0
速度自己去测。
REP STOS 估计就只有一种用法吧MEMSET?
SSE3优化
004021F0  sub         ecx,80h
004021F6  movdqa      xmmword ptr [edx],xmm0
004021FA  movdqa      xmmword ptr [edx+10h],xmm0
004021FF  movdqa      xmmword ptr [edx+20h],xmm0
00402204  movdqa      xmmword ptr [edx+30h],xmm0
00402209  movdqa      xmmword ptr [edx+40h],xmm0
0040220E  movdqa      xmmword ptr [edx+50h],xmm0
00402213  movdqa      xmmword ptr [edx+60h],xmm0
00402218  movdqa      xmmword ptr [edx+70h],xmm0
0040221D  add         edx,80h
00402223  cmp         ecx,80h
00402229  jge         004021F0

现在的编译器。。。都是这样。喜欢用体积换时间
2006-7-29 04:47
0
雪    币: 208
活跃值: (55)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
受教了!!
但如果说写每句汇编语言的时候都要考虑cpu的流水线,要考虑每种cpu的特性,要最节约cpu的时间,同时有要保证相同的人力时间而不出错,我只能说自己远远没有达到那种境界了。毕竟人不是编译器。

汇编语言不是机器指令,也要考虑人的编写和接受能力。只有cpu开心而人却累个半死(没有极端要求的情况下面)不能算好的语言,只能说作者水平高而已。的确,楼上说的很有道理,但多数人用的应该不是这种方式吧。

无论如何,非常感谢楼上。我从中大受教益!
2006-7-29 12:48
0
雪    币: 222
活跃值: (40)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
11
要打破习惯,寻求突破
2006-7-29 13:34
0
游客
登录 | 注册 方可回帖
返回
//