Diferença entre programas compilados para diferentes sistemas operacionais
8
Do ponto de vista do código compilado, qual é a diferença entre um programa compilado para um sistema operacional e outro (Linux vs Windows, por exemplo). O programa não é executado diretamente na CPU? Ou é porque o programa precisa fazer referência a bibliotecas específicas do SO?
Programas compilados comuns "executam diretamente" na CPU, mas um programa não é executado no vácuo:
Muitos programas contam com bibliotecas externas carregadas dinamicamente ( DLLsou .sobibliotecas). A maneira de vinculá-los é do compilador / vinculador, e cada sistema operacional possui padrões diferentes. No entanto, também existem programas "estaticamente vinculados" que fornecem todo o seu próprio código.
Um sistema operacional moderno não oferece controle total do computador para um programa em execução. Os programas contam com "chamadas do sistema" para E / S, acesso ao hardware e coisas como sinais e entrada no estado de suspensão. Os serviços e a interface disponíveis são definidos pelo sistema operacional. O sistema operacional também controla quais partes do sistema (memória, registros, interrupções) o programa pode usar.
Um programa GUI também deve trabalhar com o ambiente gráfico do usuário para se desenhar na tela. Mas você provavelmente já pensou nisso.
Por esses motivos, os aplicativos independentes do SO devem contar com uma "máquina virtual" de algum tipo, como a fornecida pelo Java Runtime. Fundamentalmente, uma VM fornece uma interface padrão para os recursos do SO (E / S, sinais, etc.). Obviamente, java ou python também interpretam "bytecode" em vez de lidar com as peculiaridades do conjunto de instruções da Intel; mas essa é uma história diferente.
Além disso, diferentes sistemas operacionais têm padrões diferentes para o layout da pilha, práticas de alinhamento de memória, etc.
Daniel R Hicks
Essas diferenças impediriam a execução de código compilado estaticamente? Não sabia disso ..
alexis
Provavelmente é apenas um problema teórico, pois alguma outra incompatibilidade o levaria primeiro. Porém, os sistemas operacionais geralmente têm expectativas de como os quadros de pilha são alinhados, onde os registros são armazenados etc. Isso pode variar de um sistema operacional para o outro na mesma arquitetura de hardware. Em teoria, você pode executar código "externo" puramente computacional, mas nunca seria capaz de iniciá-lo e nunca poder finalizá-lo de maneira limpa.
Daniel R Hicks
5
Sistemas operacionais diferentes também têm funcionalidades diferentes. O Windows possui portas de conclusão de E / S, o Linux não. O FreeBSD tem kqueue, o Linux não. Linux tem futexes, Windows não. Eles também têm maneiras diferentes de fazer a mesma coisa - quais parâmetros você passa para abrir um arquivo? Em que ordem eles vão? Como você invoca especificamente a função "abrir um arquivo" do sistema operacional?
ok que faz sentido, mas, em geral, faz o carregamento do programa na memória e executado no processador central, ou faz o sistema operacional "tem o controle" sobre o programa
AGZ
11
@agovizer: Ambos. Eles não são mutuamente exclusivos. Normalmente, o sistema operacional irá configurar um ambiente controlado e providenciar para que o hardware interrompa o programa em um determinado período de tempo e, em seguida, entregue o núcleo ao programa. Porém, assim que o programa atinge inúmeras condições (como uma falha de página, operação de E / S ou algo semelhante), o sistema operacional assume novamente o controle.
NÃO ! Esse é o trabalho do sistema operacional, para impedir que os aplicativos sejam executados "diretamente" na CPU. Normalmente, no nível mais baixo (ou seja, aquele em que a API do SO se baseia), um aplicativo faz interface com o kernel do sistema operacional .
É porque o próprio programa compilado precisa fazer referência a bibliotecas específicas do SO?
Sim . Muitas bibliotecas de SO são escritas para facilitar a interface com o próprio sistema operacional, mas há tantas que foram escritas para serem multiplataforma. Isso oculta a interface do SO de baixo nível do desenvolvedor e assume que a versão compilada para esse SO estará disponível em tempo de execução (veja abaixo).
Embora as bibliotecas possam ser escritas de uma forma multiplataforma, quando compiladas, elas não podem ser executadas em várias plataformas. Eles ainda precisam ser recompilados para o sistema operacional de destino específico, novamente para utilizar os componentes subjacentes específicos do sistema operacional (kernel).
Qual é a diferença entre um programa compilado para um sistema operacional e outro?
Por fim, os próprios arquivos executáveis geralmente contêm cabeçalhos de carregamento binário muito específicos e assim por diante (por exemplo, o formato de arquivo executável PE [.exe, .dll, etc ...] para Windows ou ELF para Linux [none, .o, .so , etc ...]). Isso também pode incluir código para carregar os binários específicos do SO compilados para uma biblioteca de software específica.
Por fim, da perspectiva de um programador: convocar convenção . O código compilado passa variáveis para funções de uma determinada maneira (ou seja, através de registradores ou na pilha) em uma ordem muito específica. Mesmo assim, também precisa ser acordado quem é responsável por "limpar" as chamadas de função (o chamador ou o chamado?). Embora existam várias convenções de chamada x86 padrão e amplamente usadas , algumas podem não ser suportadas por determinados sistemas operacionais (isso faz parte da ABI).
Sistemas operacionais diferentes também têm funcionalidades diferentes. O Windows possui portas de conclusão de E / S, o Linux não. O FreeBSD tem kqueue, o Linux não. Linux tem futexes, Windows não. Eles também têm maneiras diferentes de fazer a mesma coisa - quais parâmetros você passa para abrir um arquivo? Em que ordem eles vão? Como você invoca especificamente a função "abrir um arquivo" do sistema operacional?
fonte
Em geral, os programas não são compatíveis devido às diferenças em sua interface binária de aplicativo (ABI) .
NÃO ! Esse é o trabalho do sistema operacional, para impedir que os aplicativos sejam executados "diretamente" na CPU. Normalmente, no nível mais baixo (ou seja, aquele em que a API do SO se baseia), um aplicativo faz interface com o kernel do sistema operacional .
Sim . Muitas bibliotecas de SO são escritas para facilitar a interface com o próprio sistema operacional, mas há tantas que foram escritas para serem multiplataforma. Isso oculta a interface do SO de baixo nível do desenvolvedor e assume que a versão compilada para esse SO estará disponível em tempo de execução (veja abaixo).
Embora as bibliotecas possam ser escritas de uma forma multiplataforma, quando compiladas, elas não podem ser executadas em várias plataformas. Eles ainda precisam ser recompilados para o sistema operacional de destino específico, novamente para utilizar os componentes subjacentes específicos do sistema operacional (kernel).
Por fim, os próprios arquivos executáveis geralmente contêm cabeçalhos de carregamento binário muito específicos e assim por diante (por exemplo, o formato de arquivo executável PE [.exe, .dll, etc ...] para Windows ou ELF para Linux [none, .o, .so , etc ...]). Isso também pode incluir código para carregar os binários específicos do SO compilados para uma biblioteca de software específica.
Por fim, da perspectiva de um programador: convocar convenção . O código compilado passa variáveis para funções de uma determinada maneira (ou seja, através de registradores ou na pilha) em uma ordem muito específica. Mesmo assim, também precisa ser acordado quem é responsável por "limpar" as chamadas de função (o chamador ou o chamado?). Embora existam várias convenções de chamada x86 padrão e amplamente usadas , algumas podem não ser suportadas por determinados sistemas operacionais (isso faz parte da ABI).
fonte