Qual é o real propósito e uso dos registros EDI e ESI no assembler?
Eu sei que eles são usados para operações de string para uma coisa.
Alguém também pode dar um exemplo?
Qual é o real propósito e uso dos registros EDI e ESI no assembler?
Eu sei que eles são usados para operações de string para uma coisa.
Alguém também pode dar um exemplo?
Respostas:
Existem algumas operações que você só pode fazer com DI / SI (ou suas contrapartes estendidas, se você não aprendeu ASM em 1985). Entre estes estão
REP STOSB
REP MOVSB
REP SCASB
Que são, respectivamente, operações para armazenamento, carregamento e digitalização repetidos (= massa). O que você faz é configurar SI e / ou DI para apontar para um ou ambos os operandos, talvez colocar uma contagem em CX e depois deixar escapar. Essas são operações que funcionam em um monte de bytes de uma vez e meio que colocam a CPU em automático. Como você não está codificando explicitamente os loops, eles funcionam com mais eficiência (geralmente) do que um loop codificado manualmente.
Caso você esteja se perguntando: dependendo de como você configurou a operação, o armazenamento repetido pode ser algo simples, como inserir o valor 0 em um grande bloco contíguo de memória; MOVSB é usado, eu acho, para copiar dados de um buffer (bem, qualquer bando de bytes) para outro; e SCASB é usado para procurar um byte que corresponda a algum critério de pesquisa (não tenho certeza se é apenas uma pesquisa de igualdade, ou o que - você pode pesquisar :))
É para isso que servem esses regs.
SI
= Índice de origem
DI
= Índice de destino
Como outros indicaram, eles têm usos especiais com as instruções de string. Para programação em modo real, o ES
registrador de segmento deve ser usado com DI
e DS
com SI
como em
movsb es:di, ds:si
SI e DI também podem ser usados como registradores de índice de propósito geral. Por exemplo, o C
código-fonte
srcp [srcidx++] = argv [j];
compila em
8B550C mov edx,[ebp+0C]
8B0C9A mov ecx,[edx+4*ebx]
894CBDAC mov [ebp+4*edi-54],ecx
47 inc edi
onde ebp+12
contém argv
, ebx
é j
e edi
tem srcidx
. Observe que a terceira instrução usa edi
multiplicado por 4 e adiciona o ebp
deslocamento por 0x54 (a localização de srcp
); colchetes em torno do endereço indicam indireção.
AX
= acumulador
DX
= palavra dupla acumulador
CX
= contador
BX
= registro base
Eles se parecem com registradores de uso geral, mas há uma série de instruções que (inesperadamente?) Usam um deles - mas qual? - implicitamente.
Opcodes como MOVSB e MOVSW que copiam dados de forma eficiente da memória apontada pelo ESI para a memória apontada pelo EDI. Portanto,
mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!
Além das operações de string (MOVS / INS / STOS / CMPS / SCASB / W / D / Q etc.) mencionadas nas outras respostas, gostaria de acrescentar que também existem instruções de montagem x86 mais "modernas" que implicitamente usam em menos EDI / RDI:
A instrução SSE2 MASKMOVDQU
(e o próximo AVX VMASKMOVDQU
) gravam bytes seletivamente de um registro XMM na memória apontada por EDI / RDI.
Além dos registros sendo usados para operações em massa, eles são úteis por sua propriedade de serem preservados por meio de uma chamada de função (chamada preservada) na convenção de chamada de 32 bits. O ESI, EDI, EBX, EBP, ESP são preservados por chamada, enquanto EAX, ECX e EDX não são preservados por chamada. Os registros preservados de chamadas são respeitados pela função da biblioteca C e seus valores persistem por meio das chamadas da função da biblioteca C.
Jeff Duntemann em seu livro de linguagem assembly tem um exemplo de código assembly para imprimir os argumentos da linha de comando. O código usa esi e edi para armazenar contadores, pois eles não serão alterados pela função de biblioteca C printf. Para outros registradores como eax, ecx, edx, não há garantia de que eles não sejam usados pelas funções da biblioteca C.
https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025
Veja a seção 12.8 Como C vê os argumentos da linha de comando.
Observe que as convenções de chamada de 64 bits são diferentes das convenções de chamada de 32 bits, e não tenho certeza se esses registros são preservados ou não.