Pergunta

Dado um desenvolvedor proficiente com 10-20 anos de experiência que nunca construiu qualquer um compilador ou um emulador, o que seria mais do desafio?

Você poderia comparar as questões que seriam bloqueios de estradas para qualquer um.

Graças.

Foi útil?

Solução

Emulação e compilação são bastante diferentes, mas tendem a ficar agrupados por causa de tanto "de baixo nível" sendo considerado.

Emulação de uma arquitetura simples, como um Z80 6502 ou vai ser bastante simples para o pedaço de CPU do trabalho, mas haverá um pedaço justo de código para escrever, pois você precisa ter uma função para cada instrução. Você vai querer automatizar este, de alguma forma, a partir de uma especificação de conjunto de instruções com todos os horários e tal, como escrever isso tudo vai ser muito tedioso, na verdade :) Conjunto especificações de instrução CPU velhos são fáceis de encontrar, então isso ajuda muito quando a construção de emuladores.

No topo do que você vai precisar para implementar algum nível de hardware emulação , que geralmente envolve a manipulação e geração de interrupções (como a interrupção vertical-branco de um dispositivo de exibição se o emulador é para uma consola de jogos, por exemplo). Este novo vai precisar de algum nível de especificação e geração de código, mas é provável que você tem que escrever a maior parte deste à mão, uma vez que não vai ser tão repetitivo (e, portanto, automatizável) como o código de conjunto de instruções.

A compilação irá envolver algum tipo de especificação de linguagem de qualquer linguagem que você está indo para ser a implementação do compilador para, e um alvo que você vai tentar o código de saída para. A saída poderia ser direto para binário, poderia ser montagem ou até poderia ser uma outra língua (isso é realmente apenas um tradutor, mas ele conta como compilação quando o alvo é considerado "suficientemente" de baixo nível). Desde que você estará correndo em algum tipo de hardware ou plataforma VM então você será pouco provável que tenha de se preocupar com manipulação de interrupção e esse tipo de coisa.

tropeços para ambos são complexidade e correção - para o emulador que você precisa para fazê-lo funcionar de forma muito precisa a menos que você escolher coisas muito simples para emular. Você também vai precisar para criar algum tipo de depurador integrado para o emulador, caso contrário é quase impossível dizer o que está acontecendo de errado quando se invariavelmente faz isso. Para um compilador que deve ser bastante straightforwward para traduzir uma linguagem de brinquedo ou um pequeno subconjunto de uma linguagem mais complexa, e construí-lo até que você vá junto.

Lembre-se que com estes dois itens que você precisa para ser capaz de entrada de produtos para testá-los, e se você não pode produzir entradas simples, então você vai achar que é muito difícil conseguir depuração desde o início. trabalho Isto torna o compilador mais fácil de entrar, imho (Isso e que você vai querer ter algo que emula um console completo ou algo imediatamente:)

Outras dicas

Eu escrevi tanto e diria que as outras coisas sendo iguais (complexidade da língua ou conjunto de instruções), é maneira mais fácil escrever um emulador, especialmente se você está tentando escrever um interessante emulador ou compilador.

A razão é que, com um emulador que você está tentando simular uma coisa de baixo nível com o outro, coisa de baixo nível similar. Não é tão ruim. Com um compilador, você pode estar tentando implementar ideias muito de alto nível (por exemplo, objetos, funções de primeira classe, memória gerenciada, digitalização cadeia) com ferramentas muito baixo nível (palavras de máquinas e instruções de máquina). Esta tarefa é apenas muito mais difícil.

Claro que, para gangues de diversão, você pode escrever um emulador que obras de tradução binária dinâmica , que é a compilação de código de máquina para a arquitetura emulado para o código de máquina para a arquitetura nativa. Desta forma, você começa a ter toda a diversão de ambos --- e emuladores yo produto realmente rápidos, como QEMU ou o saudoso Digital FX! 32.

Eu escrevi tanto e diria que um emulador é geralmente mais fácil. Claro, isso depende muito do que você está tentando emular (emulando um mainframe IBM em um iPhone pode ser um pouco de um desafio) eo que você está tentando compilar (um pequeno compilador C é muito fácil, uma completa compilador C ++ quase incrivelmente difícil.

Isso depende em grande parte do que você está emulando, eo que você está compilando.

  • Um emulador que emula um sistema muito simples (por exemplo, uma calculadora de 4 funções) em um sistema muito capaz (por exemplo, um PC moderno) vai ser fácil de escrever.
  • Um compilador que compila uma linguagem muito simples para um único alvo (por exemplo, algo que mapeia quase diretamente para a saída de montagem) vai ser fácil de escrever.
  • Um emulador que emula um sistema muito complexo (por exemplo, um, sistema de computação grande proprietário) em um sistema muito simples (por exemplo, um PDA) será muito difícil escrever
  • Um compilador que compila uma linguagem de alto nível (por exemplo C completo ++) para muitos alvos será muito difícil escrever

Na minha opinião um compilador complexo é mais difícil de escrever do que um emulador complexo para o simples razão de que o compilador envolve muito mais teoria.

Ao projetar seu idioma XX, há uma série de factores a considerar para não falar de otimizar a saída do código gerado compilador que é uma arte em si. Com um emulador você tem um ambiente já bem definida com uma linguagem em sua maioria bem definido que você deseja implementar.

Em qualquer caso eu recomendo a ninguém para escrever e escrever um compilador porque lhe dá uma compreensão mais profunda da programação, assim como as necessidades médico para saber sobre a anatomia do corpo, embora ele não pode precisar dele em seu trabalho diário.

EDIT: Eu acho que ambas as habilidades são muito úteis e um pode realmente combiná-los - eles não são XOR.

Gostaria de acrescentar a minha opinião acima é que a criação de uma linguagem de programação não-trivial incluindo runtime-bibliotecas para interagir com motoristas, bancos de dados, etc, e que pode evoluir com versões futuras mas continuam a ser compatíveis com versões anteriores é um dos mais desafiador áreas em CS.

Também concordo que, se a plataforma é desconhecida ou seja, você é engenharia reversa algo, então é muito mais difícil de fazer um emulador, mas OTOH que não é o que a pergunta do OP era, era?

A emulação de software é bem simples e assim relativamente fácil, mas pode ser tedioso.

Escrevendo um compilador pode ser muito difícil, mas é mais simples, quer ter um bom trabalho-conhecimento ou por ter um bom conjunto de especificações (por exemplo, a notação Backus-Naur Form) da língua que você está escrevendo o compilador para.

A emulação de hardware pode ser extremamente difícil, se seu objetivo é fazer com que o trabalho emulador em muitas plataformas diferentes (por exemplo, executar a emulação de trabalho de tempo poder de uma unidade de disco flexível sob MSDOS usando as constantes fudge corretos, mas a emulação falha em uma plataforma de multitarefa como o Vista ou Linux). emulação de hardware também é extremamente difícil quando o conhecimento insuficiente disponível sobre como o seu modo de operação é controlada por software. Este forças de longo e chato engenharia reversa antes de progresso pode ser feito.

Ao todo, I emulação juiz para ser o mais difícil.

Escrevendo um emulador para uma plataforma emulado conhecido que não é difícil (você também pode usar um emulador de CPU pré-fabricados e ganhar algum tempo de desenvolvimento).

Escrevendo um emulador para hardware emulado desconhecido é muito mais difícil , e as mudanças a dificuldade de campos diferentes a partir do código-desenvolvimento: matemática, cryptoanalysis, protocolos de segurança, etc. E, como um desenvolvedor, você tem que tem paciência para a tentativa e erro envolvido no processo.

Como exemplo, basta pensar em quanto tempo CPS2 emulação necessários (ROMs CPS2 foram criptografado).

Fora de contexto, não pode haver respostas definitivas: tudo depende do que você quer alcançar, e que você está competindo contra

.

Se é apenas uma "prova de conceito", em seguida, em ambos os casos, é bastante simples.

Mas se você está tentando emular um hardware complexo ou com alta precisão, ou se você quiser alcançar a qualidade de compilação AAA, as coisas podem tornar-se rapidamente de complexidade feio. A complexidade não aparecerá apenas no algoritmos / teoria do código "principal", mas também em todas as ferramentas de suporte que você vai ter que construir (depuradores, disassemblers, profilers, etc.) para que você possa avançar para a próxima etapa.

Dito isso, outro aspecto a considerar é que escrever um compilador trabalhar para praticamente qualquer linguagem de programação lá fora é de complexidade razoável. Por outro lado, se houver hardware lá fora, que é trivial para emular, também há hardware para o qual escrevendo mesmo um emulador básico pode ser muito complexo.

Assim, pintando com um pincel largo, eu diria que escrever um compilador é mais fácil, porque você está praticamente garantido para ter sucesso na obtenção de uma versão de trabalho, independentemente do hardware ou língua-alvo. Não existe tal garantia para um emulador.

Escrevendo um compilador é muito mais difícil, uma vez que você está lidando com muita coisa de nível inferior (ligando, montagem que é específico para sua arquitetura, etc).

Um emulador só tem que executar a lógica de cada instrução alimentado a ele (e eu sei que estou simplificando isso, mas eu suponho que você tem as especificações para o conjunto de instruções), agora, escrever um emulador FAST é muito mais difícil.

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