好吧,我知道CLD清除方向标志,STD设置方向标志。 但设置和清除方向标志的重点是什么?
答案 0 :(得分:31)
方向标志用于影响字符串指令偏移指针寄存器的方向。这些是可以使用with the REP
prefix重复操作的相同指令。
(虽然lods
对rep
}不是很有用。
字符串指令是:MOVS
(将mem复制到mem),STOS
(存储AL / AX / EAX / RAX),SCAS
(扫描字符串),{{1} }(比较字符串)和CMPS
(加载字符串)。还有LODS
/ ins
用于在内存和IO端口之间进行复制。这些指令中的每一个都有字节,字,双字和qword操作数大小。
简而言之,当direction标志为0时,指令的工作方式是在每次迭代后将指针递增到数据(直到outs
为零或其他条件,具体取决于{{1的味道如果标志为1,则指针递减。
例如,movsd
将dword从ECX
复制到REP
(或64位模式下的rdi),并执行此操作:(请参阅链接中的“操作”部分从英特尔的PDF中提取的ISA参考手册条目
[ds:esi]
使用REP前缀,它执行ECX次,现代x86 CPU优化了“快速字符串”微码,可以使用16字节或32字节内部操作进行复制(或[es:edi]
存储)。另见this Q&A about memory bandwidth and the ERMSB feature。 (请注意,只有dword [es:edi] = dword [ds:esi] // 4-byte copy memory to memory
if (DF == 0)
esi += 4;
edi += 4;
else // DF == 1
esi -= 4;
edi -= 4;
fi
和stos
以这种方式进行优化,而不是rep stos
或rep movs
)。
答案 1 :(得分:8)
CLD CLears Direction标志,数据继续。 STD Sends Direction标志,数据倒退。
答案 2 :(得分:3)
如果使用Windows,那么按照STDCALL调用约定 -
在STDCALL下,方向标志在进入时是清除的,必须是 回来了。
因此,如果您设置DF,那么在API调用之前,您必须清除它。
答案 3 :(得分:3)
CLD:清除方向标志使字符串指针 每次字符串操作后自动递增
STD: std用于将方向标志设置为1,以便当其中一个字符串指令执行时,SI和/或DI将自动递减以指向下一个字符串元素。如果设置了方向标志,则SI / DI将递减1表示字节字符串,2表示字串。
这个答案对你有帮助。
答案 4 :(得分:1)
CLD: 清除EFLAGS寄存器中的DF标志。当DF标志设置为0时,字符串操作将递增索引寄存器(ESI和/或EDI)。
这是一个简单的示例:
List<double>
(汇编并与section .text
global main
main:
mov ecx, len
mov esi, s1
mov edi, s2
cld ; redundant because DF is already guaranteed to be 0 on function entry
; but included for illustration purposes
loop_here:
lodsb ; AL=[esi], ESI+=1 (because DF=0, otherwise ESI-=1)
add al, 02
stosb ; [edi]=AL, EDI+=1 (because DF=0, otherwise EDI-=1)
loop loop_here ; like dec ecx / jnz but without setting flags
; ECX=0, EDI and ESI pointing to the end of their buffers
mov edx, len-1 ;message length, not including the terminating 0 byte
mov ecx,s2 ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
xor ebx,ebx
int 0x80 ;call kernel: sys_exit(0)
section .data
s1: db 'password', 0 ; source buffer
len equ $-s1
section .bss
s2: resb len ; destination buffer
链接。或者,如果需要,可以将其链接为静态文件nasm -felf32 caesar.asm && gcc -no-pie -m32 caesar.o -o caesar
而不是_start
的可执行文件。)
(此示例尝试实现Caesar密码。)