ESI的目的和; EDI注册?

时间:2009-12-06 19:26:38

标签: assembly x86

EDI& amp;的实际目的和用途是什么? ESI在汇编程序中注册?

我知道它们只用于字符串操作。

有人也举个例子吗?

5 个答案:

答案 0 :(得分:75)

SI =来源索引
DI =目的地索引

正如其他人所指出的那样,它们具有字符串指令的特殊用途。对于实模式编程,ES段寄存器必须与DIDS SI一起使用,如

movsb  es:di, ds:si

SI和DI也可用作通用索引寄存器。例如,C源代码

srcp [srcidx++] = argv [j];

编译成

8B550C         mov    edx,[ebp+0C]
8B0C9A         mov    ecx,[edx+4*ebx]
894CBDAC       mov    [ebp+4*edi-54],ecx
47             inc    edi

ebp+12包含argvebxjedisrcidx。请注意,第三条指令使用edi mulitplied by 4并将ebp偏移量加上0x54(srcp的位置);地址周围的括号表示间接。

<小时/> 虽然我不记得我在哪里看到它,但this确认了大部分内容,this(幻灯片17)确认了其他内容:

AX =累加器
DX =双字累加器
CX =计数器
BX =基址寄存器

它们看起来像通用寄存器,但有许多指令(意外地?)使用其中一个 - 但是哪一个? - 明显地。

答案 1 :(得分:70)

如果您在1985年没有学习ASM,那么您可以对DI / SI(或其扩展对应物)进行一些操作。其中有

REP STOSB
REP MOVSB
REP SCASB

分别是重复(=质量)存储,加载和扫描的操作。你做的是你设置SI和/或DI指向一个或两个操作数,也许在CX中计数然后让我们翻录。这些操作一次只能处理一堆字节,它们可以自动处理CPU。因为你没有明确地编写循环,所以它们(通常)比手动编码循环更有效地完成它们的工作。

万一你想知道:根据你设置操作的方式,重复存储可以很简单,比如将值0打到一个大的连续内存块中;我认为,MOVSB用于将数据从一个缓冲区(以及任何字节串)复制到另一个缓冲区;和SCASB用于查找匹配某些搜索条件的字节(我不确定它是否只搜索相等,或者是什么 - 你可以查找它:))

这就是那些注册表的大部分内容。

答案 2 :(得分:32)

像MOVSB和MOVSW这样的操作码可以有效地将数据从ESI指向的内存复制到EDI指向的内存中。因此,

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!

答案 3 :(得分:11)

除了其他答案中提到的字符串操作(MOVS / INS / STOS / CMPS / SCASB / W / D / Q等)之外,我想补充说还有更多“现代”x86汇编指令,隐式使用至少EDI / RDI:

SSE2 MASKMOVDQU(和即将发布的AVX VMASKMOVDQU)指令有选择地将字节从XMM寄存器写入EDI / RDI指向的存储器。

答案 4 :(得分:4)

除了用于批量操作的寄存器之外,它们对于通过32位调用约定中的函数调用(调用保留)保留的属性很有用。 ESI,EDI,EBX,EBP,ESP是呼叫保留的,而EAX,ECX和EDX不是呼叫保留的。 C库函数遵循调用保留的寄存器,它们的值通过C库函数调用保持不变。

Jeff Duntemann在他的汇编语言书中有一个用于打印命令行参数的汇编代码示例。该代码使用esi和edi来存储计数器,因为它们将由C库函数printf保持不变。对于其他寄存器,如eax,ecx,edx,无法保证它们不被C库函数使用。

https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

参见12.8 C如何看到命令行参数。

请注意,64位调用约定与32位调用约定不同,我不确定这些寄存器是否是调用保留的。