Pergunta

Eu escrevi um programa de "perigoso" em C ++ que salta para trás e para diante de um quadro de pilha para outra. O objetivo é ser salto do nível mais baixo de uma pilha de chamadas para um chamador, fazer alguma coisa, e depois saltar de volta para baixo outra vez, cada vez que pular todas as chamadas no meio.

Eu faço isso por mudar manualmente o endereço de base da pilha (ajuste %ebp) e saltar para um endereço rótulo. Ele funciona totalmente, com gcc e ICC ambos, sem qualquer corrupção de pilha em tudo. No dia isso funcionou foi um dia legal.

Agora estou tendo o mesmo programa e está escrevendo-lo em C, e ele não funciona. Especificamente, ele não funciona com v4.0.1 gcc (Mac OS). Uma vez que eu saltar para o novo quadro de pilha (com a pilha de base set ponteiro corretamente), as seguintes instruções executar, sendo pouco antes de uma chamada para fprintf. A última instrução aqui falhar, dereferencing NULL:

lea    0x18b8(%ebx), %eax
mov    (%eax), %eax
mov    (%eax), %eax

Eu fiz alguma depuração, e eu descobri que, definindo o %ebx registrar manualmente quando eu mudar quadros de pilha (usando um valor observei antes de deixar a função, em primeiro lugar), eu corrigir o erro. Eu li que este registo lida com "código independente de posição" no gcc.

O que é código independente de posição? Como funciona o código de posição independente? Para o que é este apontar registo?

Foi útil?

Solução

PIC é o código que é realocado dinamicamente quando ele é carregado. Código que é não-PIC tem endereços de salto e de chamadas definidos no momento da ligação. PIC tem uma tabela que faz referência a todos os lugares onde existam tais valores, bem como um .dll.

Quando a imagem é carregada, o carregador irá atualizar dinamicamente esses valores. Outros esquemas de referência a um valor de dados que define uma "base" e o endereço de destino é decidido através da realização de cálculos na base. A base é geralmente definida pelo carregador novamente.

Finalmente, outros esquemas de usar vários trampolins que chamada para deslocamentos relativos conhecidos. Os deslocamentos relativos conter código e / ou dados que são atualizados por um carregador.

Existem várias razões pelas quais diferentes esquemas são escolhidos. Alguns são rápidos quando executado, mas mais lento para carregar. Alguns são rápidos para carregar, mas tem desempenho menos tempo de execução.

Outras dicas

EBX aponta para o Mundial offset Table. Consulte esta referência sobre PIC em i386 . O link explica o PIC é um como EBX é usado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top