eh bien, je sais que le CLD efface le drapeau de direction et que STD active le drapeau de direction. mais à quoi sert-il d’établir et de dégager le drapeau de direction?
L'indicateur de direction est utilisé pour influencer la direction dans laquelle les instructions de chaîne décalent les registres du pointeur. Ce sont les mêmes instructions que vous pouvez utiliser avec le préfixe REP
pour répéter l’opération . (Bien que lods
ne soit pas très utile avec rep
).
Les instructions de chaîne sont les suivantes: MOVS
(copier de mémoire en mémoire), STOS
(magasin AL/AX/EAX/RAX), SCAS
(chaîne d'analyse), CMPS
(chaîne de comparaison) et LODS
(chaîne de chargement). Il y a aussi ins
/outs
pour copier entre la mémoire et un port IO. Chacune de ces instructions est disponible en tailles d'opérandes octets, Word, dword et qword.
En résumé, lorsque l'indicateur de direction est 0, les instructions fonctionnent en incrémentant le pointeur sur les données après chaque itération (jusqu'à ce que ECX
soit égal à zéro ou à une autre condition, selon le style du préfixe REP
), tandis que si l'indicateur est 1 , le pointeur est décrémenté.
Par exemple, movsd
copie un dword de [ds:esi]
dans [es:edi]
(ou rdi en mode 64 bits) et fait ceci: (Voir la section "Opération" de l'entrée de manuel de référence ISA liée extraite du fichier Intel PDF)
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
Avec un préfixe REP, il effectue cette opération ECX fois, et les processeurs modernes x86 ont un microcode optimisé "chaînes rapides" qui effectue la copie (ou le stockage stos
) avec des opérations internes de 16 octets ou de 32 octets. Voir également ce document sur la bande passante mémoire et la fonctionnalité ERMSB . (Notez que seuls rep stos
et rep movs
sont optimisés de cette façon, et non pas repne/repe scas
ou cmps
).
CLD Efface l'indicateur de direction, les données sont transférées . STD Sélectionne l'indicateur de direction, les données sont inversées.
CLD: efface l'indicateur de direction pour que la chaîne soit dirigée vers les pointeurs incrémentation automatique après chaque opération de chaîne
STD: Std est utilisé pour définir l'indicateur de direction sur 1 afin que SI et/ou DI soient automatiquement décrémentés pour pointer sur l'élément de chaîne suivant lors de l'exécution de l'une des instructions de chaîne. DI sera décrémenté de 1 pour les chaînes d'octets et de 2 pour les chaînes de mots.
Cette réponse peut être utile pour vous.
Si vous utilisez Windows, alors, conformément à la convention d'appel de STDCALL -
Sous STDCALL, l'indicateur de direction est dégagé à l'entrée et doit être retourné clair.
Ainsi, si vous définissez DF, vous devez l'effacer avant d'appeler une API.
CLD: Efface l'indicateur DF dans le registre EFLAGS. Lorsque l'indicateur DF est défini sur 0, les opérations sur les chaînes incrémentent les registres d'index (ESI et/ou EDI).
voici un exemple simple:
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
(assemblez et liez avec nasm -felf32 caesar.asm && gcc -no-pie -m32 caesar.o -o caesar
. Ou liez-le dans un exécutable statique avec ceci comme _start
au lieu de main
si vous voulez.)
(Cet exemple a essayé d'implémenter le chiffrement de César.)