Eu estava lendo outra questão relativa à eficiência de duas linhas de código, e o OP disse que olhou para o assembly por trás do código e as duas linhas eram idênticas no assembly. Digressão à parte, como eu poderia ver o código assembly criado quando um programa é compilado.
Estou usando o Visual C ++ da Microsoft, mas também gostaria de saber se é possível visualizar o assembly por trás do código escrito em Visual Basic.
Então, como posso ver o código assembly por trás de um programa escrito em linguagens de nível superior como C ++ e Visual Basic?
visual-c++
assembly
Bart
fonte
fonte
Respostas:
Existem várias abordagens:
Normalmente, você pode ver o código assembly enquanto depura C ++ no visual studio (e eclipse também). Para isso no Visual Studio coloque um ponto de interrupção no código em questão e quando o depurador acertar, clique com o botão direito e encontre "Go To Assembly" (ou pressione CTRL + ALT + D)
A segunda abordagem é gerar listagens de montagem durante a compilação. Para isso, vá em configurações do projeto -> C / C ++ -> Arquivos de saída -> Localização da lista ASM e preencha o nome do arquivo. Selecione também "Saída da montagem" para "Montagem com código fonte".
Compile o programa e use qualquer depurador de terceiros. Você pode usar OllyDbg ou WinDbg para isso. Além disso, você pode usar IDA (desmontador interativo). Mas essa é uma maneira radical de fazer isso.
fonte
Observação adicional: há uma grande diferença entre a saída do assembler de depuração e a versão um. O primeiro é bom para aprender como o compilador produz código assembler a partir de C ++. O segundo é bom para aprender como o compilador otimiza várias construções C ++. Nesse caso, algumas transformações de C ++ para asm não são óbvias.
fonte
Especifique a opção / FA para o compilador cl. Dependendo do valor da opção, apenas o código de montagem ou o código de alto nível e o código de montagem são integrados. O nome do arquivo obtém a extensão de arquivo .asm. Aqui estão os valores suportados:
fonte
A maneira mais fácil é disparar o depurador e verificar a janela de desmontagem .
fonte
A versão anterior desta resposta (um "hack" para rextester.com) é basicamente redundante agora que http://gcc.godbolt.org/ fornece CL 19 RC para ARM, x86 e x86-64 (visando a convenção de chamada do Windows , ao contrário de gcc, clang e icc nesse site).
O explorador do compilador Godbolt é projetado para formatar bem a saída do compilador asm, removendo o "ruído" das diretivas, então eu recomendo usá-lo para olhar asm para funções simples que pegam args e retornam um valor (então eles não serão otimizado).
Por um tempo, CL estava disponível em http://gcc.beta.godbolt.org/, mas não no site principal, mas agora está em ambos.
Para obter a saída do ASM MSVC do http://rextester.com/l/cpp_online_compiler_visual compilador online: Adicione
/FAs
às opções de linha de comando. Faça com que seu programa encontre seu próprio caminho, trabalhe o caminho para o.asm
e descarte-o. Ou execute um desmontador no.exe
.por exemplo, http://rextester.com/OKI40941
type
é a versão DOS decat
. Eu não queria incluir mais código que tornaria mais difícil encontrar as funções para as quais eu queria ver o conjunto. (Embora usando std :: string e boost run counter para esses objetivos! Alguma manipulação de string de estilo C que faz mais suposições sobre a string que está processando (e ignora a segurança / alocação de comprimento máximo usando um grande buffer) no resultado deGetModuleFileNameA
seria ser muito menos código de máquina total.)IDK por que, mas
cout << p.string() << endl
mostra apenas o nome de base (ou seja, o nome do arquivo, sem os diretórios), embora a impressão de seu comprimento mostre que não é apenas o nome básico. (Chromium48 no Ubuntu 15.10). Provavelmente há algum processamento de escape de barra invertida em algum pontocout
ou entre o stdout do programa e o navegador da web.fonte
.c_str()
imprime o que parece ser um ponteiro. Se você seguir o link, verá o código para hexdump astd::string
(desabilitado com#if 0
). Acontece que a string está boa, mascout
não está sendo enviada para o navegador da web. Também não há caracteres não ASCII, apenas barras invertidas.subdir--; p /= *subdir;
isso, você não reduziu p apenas ao nome do arquivo? Ou talvez eu esteja entendendo mal o que você está tentando imprimir.subdir--
seguido porp /= *subdir
quandosubdir
foi originalmentep.end()
GetModuleFileNameA
estava apenas voltandoa.exe
. Só depois de fazer o feitiço e imprimir o comprimento é que eu sabia que estava funcionando e poderia fazer com que o programa manipulasse o caminho, simplesmente não conseguia imprimir o caminho\\r
(bem\r
quando o compilador produz) do nome do arquivo que traduziu mal ao renderizar para o navegador da web. Usandop.generic_string()
funciona, mas as barras invertidas são barras normais.No Visual C ++, as opções de projeto em Arquivos de saída, acredito que tem uma opção para gerar a listagem ASM com código-fonte. Portanto, você verá o código-fonte C / C ++ e o ASM resultante no mesmo arquivo.
fonte
Para MSVC, você pode usar o vinculador.
link.exe / dump / linho / disasm /out:foo.dis foo.dll
foo.pdb precisa estar disponível para obter símbolos
fonte
O .NET Reflector da Red Gate é uma ferramenta incrível que me ajudou várias vezes. O lado positivo desse utilitário além de mostrar facilmente a MSIL é que você pode analisar muitas DLLs de terceiros e fazer com que o Reflector se encarregue da conversão de MSIL em C # e VB.
Não estou prometendo que o código será tão claro quanto o código-fonte, mas você não terá muitos problemas para segui-lo.
fonte
Se você está falando sobre depuração para ver o código assembly, a maneira mais fácil é Depurar-> Windows-> Desmontagem (ou Alt-8). Isso permitirá que você entre em uma função chamada e permaneça em Disassembly.
fonte