Isso executará o pré-processador (cpp) no helloworld.c, executará a compilação inicial e parará antes que o assembler seja executado.
Por padrão, isso produzirá um arquivo helloworld.s. O arquivo de saída ainda pode ser definido usando a -oopção
gcc -S -o my_asm_output.s helloworld.c
Claro que isso só funciona se você tiver a fonte original. Uma alternativa se você tiver apenas o arquivo de objeto resultante é usar objdump, definindo a --disassembleopção (ou -dpara o formulário abreviado).
Essa opção funciona melhor se a opção de depuração estiver ativada para o arquivo de objeto ( -gno momento da compilação) e o arquivo não tiver sido removido.
A execução file helloworldfornecerá algumas indicações sobre o nível de detalhes que você obterá usando o objdump.
Embora isso esteja correto, achei os resultados da resposta de Cr McDonough mais úteis.
Rhys Ulerich
3
um uso adicional: objdump -M intel -S - desmonte o helloworld> helloworld.dump para obter o despejo de objetos na sintaxe da intel compatível com o nasm no linux.
touchStone 11/03/2015
2
Se você tem uma única função para otimizar / verificação, então você pode dar uma tentativa para online interativa compiladores C ++ ou seja Godbolt
fiorentinoing
11
@touchStone: O GAS não.intel_syntax é compatível com o NASM . É mais parecido com o MASM (por exemplo, mov eax, symbolé uma carga, diferente do NASM, onde é um mov r32, imm32endereço), mas também não é totalmente compatível com o MASM. Eu o recomendo como um bom formato para ler, especialmente se você gosta de escrever na sintaxe do NASM. objdump -drwC -Mintel | lessou gcc foo.c -O1 -fverbose-asm -masm=intel -S -o- | lesssão úteis. (Veja também Como remover “ruído” da saída do conjunto GCC / clang? ). -masm=inteltrabalha com clang também.
Peter Cordes
3
Melhor usogcc -O -fverbose-asm -S
Basile Starynkevitch
173
Isso gerará código de montagem com o código C + números de linha entrelaçados, para ver mais facilmente quais linhas geram qual código:
(Isso é realmente na página (numerada) 3 (que é a página 15 do PDF))
Grumdrig
11
Infelizmente, asno OS X não conhece essas bandeiras. Se isso acontecesse, você provavelmente poderia usar uma linha -Wapara passar as opções para as.
Grumdrig
23
g++ -g -O0 -c -fverbose-asm -Wa,-adhln test.cpp > test.lstseria a versão abreviada disso.
Legends2k #
4
Você também pode usar gcc -c -g -Wa,-ahl=test.s test.corgcc -c -g -Wa,-a,-ad test.c > test.txt
phuclv
11
Uma postagem no blog explicando isso com mais detalhes, incluindo a versão de comando único como lendas e Lu'u postadas. Mas porque -O0? Está cheio de cargas / lojas que dificultam o rastreamento de um valor e não informa nada sobre a eficiência do código otimizado.
@Paladin - Não necessariamente. O OP tinha como objetivo obter o equivalente de saída do assembler do código-fonte C / C ++, isso obtém a Listagem, que eu concordo é mais útil para entender o que o compilador e o otimizador estão fazendo. Mas isso faria com que o próprio montador vomitasse, pois não esperava os números das linhas, e compilou os bytes fora das instruções de montagem.
Jesse Chisholm
Use pelo menos -O2as opções de otimização que você realmente usa ao criar seu projeto, se quiser ver como o gcc otimiza seu código. (Ou se você usar LTO, como você deve, então você tem que desmontar a saída vinculador para ver o que realmente se.)
Verifique o FAQ: "Também é perfeitamente bom perguntar e responder sua própria pergunta de programação". O ponto é que agora o StackOverflow contém as perguntas e respostas como um recurso para outros.
Steve Jessop
E talvez alguém vai vir e surpreendê-lo com uma resposta melhor, embora o meu pode ser um pouco detalhado, às vezes ...
PhirePhly
Existe até o botão de resposta da sua própria pergunta.
Ciro Santilli escreveu
13
Se o que você deseja ver depende da vinculação da saída, então o objdump no arquivo / executável do objeto de saída também pode ser útil além do gcc -S acima mencionado. Aqui está um script muito útil de Loren Merritt que converte a sintaxe objdump padrão na sintaxe nasm mais legível:
#!/usr/bin/perl -w
$ptr='(BYTE|WORD|DWORD|QWORD|XMMWORD) PTR ';
$reg='(?:[er]?(?:[abcd]x|[sd]i|[sb]p)|[abcd][hl]|r1?[0-589][dwb]?|mm[0-7]|xmm1?[0-9])';
open FH,'-|','/usr/bin/objdump','-w','-M','intel',@ARGVordie;
$prev ="";while(<FH>){if(/$ptr/o){
s/$ptr(\[[^\[\]]+\],$reg)/$2/o or
s/($reg,)$ptr(\[[^\[\]]+\])/$1$3/o or
s/$ptr/lc $1/oe;}if($prev =~/\t(repz )?ret /and
$_ =~/\tnop |\txchg *ax,ax$/){# drop this line}else{print $prev;
$prev = $_;}}print $prev;
close FH;
Eu suspeito que isso também pode ser usado na saída do gcc -S.
Ainda assim, esse script é um hack sujo que não converte completamente a sintaxe. Por exemplo, mov eax,ds:0x804b794não é muito NASMish. Além disso, às vezes, apenas retira informações úteis: movzx eax,[edx+0x1]deixa o leitor adivinhar se o operando da memória era byteou word.
Ruslan
Para desmontar a sintaxe do NASM, use o Agner Fog'sobjconv . Você pode desmontá-lo no stdout com o arquivo de saída = /dev/stdout, para que possa ser lessvisualizado. Também existe ndisasm, mas desmonta apenas binários planos e não sabe sobre arquivos de objetos (ELF / PE).
27516 Peter
9
Como todos apontaram, use a -Sopção para o GCC. Gostaria também de acrescentar que os resultados podem variar (muito!), Dependendo de você adicionar ou não opções de otimização ( -O0por nenhuma, -O2para otimização agressiva).
Em arquiteturas RISC, em particular, o compilador geralmente transformará o código quase além do reconhecimento na otimização. É impressionante e fascinante ver os resultados!
Bem, como todos disseram, use a opção -S. Se você usar a opção -save-temps, também poderá obter arquivo pré-processado ( .i), arquivo de montagem ( .s) e arquivo de objeto (*. O). (obtenha cada um deles usando -E, -S e -c.)
Como mencionado anteriormente, observe o sinalizador -S.
Também vale a pena examinar a família de sinalizadores '-fdump-tree', em particular '-fdump-tree-all', que permite ver algumas das formas intermediárias do gcc. Isso geralmente pode ser mais legível que o assembler (pelo menos para mim) e permite que você veja o desempenho das passagens de otimização.
Não vejo essa possibilidade entre as respostas, provavelmente porque a pergunta é de 2008, mas em 2018 você pode usar o site online de Matt Goldbolt https://godbolt.org
Se você deseja fazer isso para um grande número de arquivos, considere usar:
-save-temps=obj
que salva os arquivos intermediários no mesmo diretório que a -osaída do objeto em vez do diretório de trabalho atual, evitando possíveis conflitos de nome de base.
Outra coisa interessante sobre essa opção é se você adicionar -v:
gcc -save-temps -c -o main.o -v main.c
na verdade, mostra os arquivos explícitos sendo usados em vez de temporários feios /tmp, por isso é fácil saber exatamente o que está acontecendo, o que inclui as etapas de pré-processamento / compilação / montagem:
Para exibir no terminal, use gcc foo.c -masm=intel -fverbose-asm -O3 -S -o- |less. -Spor conta própria cria foo.s.
Peter Cordes
2
Recentemente, eu queria conhecer a montagem de cada função em um programa,
foi assim que eu fiz.
$ gcc main.c // main.c source file
$ gdb a.exe // gdb a.out in linux(gdb) disass main // note here main is a function// similary it can be done for other functions
Aqui, a primeira parte armazena a saída de montagem do programa no mesmo nome de arquivo que o Programa, mas com uma extensão .s alterada , você pode abri-lo como qualquer arquivo de texto normal.
A segunda parte aqui compila seu programa para uso real e gera um executável para o seu programa com um nome de arquivo especificado.
O program.c usado acima é o nome do seu programa e a saída é o nome do executável que você deseja gerar.
Respostas:
Use a
-S
opção para gcc (ou g ++).Isso executará o pré-processador (cpp) no helloworld.c, executará a compilação inicial e parará antes que o assembler seja executado.
Por padrão, isso produzirá um arquivo
helloworld.s
. O arquivo de saída ainda pode ser definido usando a-o
opçãoClaro que isso só funciona se você tiver a fonte original. Uma alternativa se você tiver apenas o arquivo de objeto resultante é usar
objdump
, definindo a--disassemble
opção (ou-d
para o formulário abreviado).Essa opção funciona melhor se a opção de depuração estiver ativada para o arquivo de objeto (
-g
no momento da compilação) e o arquivo não tiver sido removido.A execução
file helloworld
fornecerá algumas indicações sobre o nível de detalhes que você obterá usando o objdump.fonte
.intel_syntax
é compatível com o NASM . É mais parecido com o MASM (por exemplo,mov eax, symbol
é uma carga, diferente do NASM, onde é ummov r32, imm32
endereço), mas também não é totalmente compatível com o MASM. Eu o recomendo como um bom formato para ler, especialmente se você gosta de escrever na sintaxe do NASM.objdump -drwC -Mintel | less
ougcc foo.c -O1 -fverbose-asm -masm=intel -S -o- | less
são úteis. (Veja também Como remover “ruído” da saída do conjunto GCC / clang? ).-masm=intel
trabalha com clang também.gcc -O -fverbose-asm -S
Isso gerará código de montagem com o código C + números de linha entrelaçados, para ver mais facilmente quais linhas geram qual código:
Encontrado em Algoritmos para programadores , página 3 (que é a 15ª página geral do PDF).
fonte
as
no OS X não conhece essas bandeiras. Se isso acontecesse, você provavelmente poderia usar uma linha-Wa
para passar as opções paraas
.g++ -g -O0 -c -fverbose-asm -Wa,-adhln test.cpp > test.lst
seria a versão abreviada disso.gcc -c -g -Wa,-ahl=test.s test.c
orgcc -c -g -Wa,-a,-ad test.c > test.txt
-O0
? Está cheio de cargas / lojas que dificultam o rastreamento de um valor e não informa nada sobre a eficiência do código otimizado.A seguinte linha de comando é do blog de Christian Garbin
Executei o G ++ a partir de uma janela do DOS no Win-XP, em uma rotina que contém uma conversão implícita
A saída é um código gerado montado, intercalado com o código C ++ original (o código C ++ é mostrado como comentários no fluxo asm gerado)
fonte
-O2
as opções de otimização que você realmente usa ao criar seu projeto, se quiser ver como o gcc otimiza seu código. (Ou se você usar LTO, como você deve, então você tem que desmontar a saída vinculador para ver o que realmente se.)Use a opção -S
ou também com o gcc
Veja também isso
fonte
Se o que você deseja ver depende da vinculação da saída, então o objdump no arquivo / executável do objeto de saída também pode ser útil além do gcc -S acima mencionado. Aqui está um script muito útil de Loren Merritt que converte a sintaxe objdump padrão na sintaxe nasm mais legível:
Eu suspeito que isso também pode ser usado na saída do gcc -S.
fonte
mov eax,ds:0x804b794
não é muito NASMish. Além disso, às vezes, apenas retira informações úteis:movzx eax,[edx+0x1]
deixa o leitor adivinhar se o operando da memória erabyte
ouword
.objconv
. Você pode desmontá-lo no stdout com o arquivo de saída =/dev/stdout
, para que possa serless
visualizado. Também existendisasm
, mas desmonta apenas binários planos e não sabe sobre arquivos de objetos (ELF / PE).Como todos apontaram, use a
-S
opção para o GCC. Gostaria também de acrescentar que os resultados podem variar (muito!), Dependendo de você adicionar ou não opções de otimização (-O0
por nenhuma,-O2
para otimização agressiva).Em arquiteturas RISC, em particular, o compilador geralmente transformará o código quase além do reconhecimento na otimização. É impressionante e fascinante ver os resultados!
fonte
Bem, como todos disseram, use a opção -S. Se você usar a opção -save-temps, também poderá obter arquivo pré-processado ( .i), arquivo de montagem ( .s) e arquivo de objeto (*. O). (obtenha cada um deles usando -E, -S e -c.)
fonte
Como mencionado anteriormente, observe o sinalizador -S.
Também vale a pena examinar a família de sinalizadores '-fdump-tree', em particular '-fdump-tree-all', que permite ver algumas das formas intermediárias do gcc. Isso geralmente pode ser mais legível que o assembler (pelo menos para mim) e permite que você veja o desempenho das passagens de otimização.
fonte
Se você está procurando montagem LLVM:
fonte
Não vejo essa possibilidade entre as respostas, provavelmente porque a pergunta é de 2008, mas em 2018 você pode usar o site online de Matt Goldbolt https://godbolt.org
Você também pode clonar git localmente e executar o projeto https://github.com/mattgodbolt/compiler-explorer
fonte
-save-temps
Isso foi mencionado em https://stackoverflow.com/a/17083009/895245, mas deixe-me exemplificar ainda mais.
A grande vantagem dessa opção
-S
é que é muito fácil adicioná-la a qualquer script de construção, sem interferir muito na própria construção.Quando você faz:
main.c
e agora, além da saída normal
main.o
, o diretório de trabalho atual também contém os seguintes arquivos:main.i
é um bônus e contém o arquivo pré-processado:main.s
contém a montagem gerada desejada:Se você deseja fazer isso para um grande número de arquivos, considere usar:
que salva os arquivos intermediários no mesmo diretório que a
-o
saída do objeto em vez do diretório de trabalho atual, evitando possíveis conflitos de nome de base.Outra coisa interessante sobre essa opção é se você adicionar
-v
:na verdade, mostra os arquivos explícitos sendo usados em vez de temporários feios
/tmp
, por isso é fácil saber exatamente o que está acontecendo, o que inclui as etapas de pré-processamento / compilação / montagem:Testado no Ubuntu 19.04 amd64, GCC 8.3.0.
fonte
Use a opção -S:
fonte
De: http://www.delorie.com/djgpp/v2faq/faq8_20.html
gcc -c -g -Wa, -a, -ad [outras opções do GCC] foo.c> foo.lst
em alternativa à resposta de PhirePhly Ou apenas use -S como todos disseram.
fonte
Aqui estão as etapas para ver / imprimir o código de montagem de qualquer programa C no Windows
console / terminal / prompt de comando:
Escreva um programa C em um editor de código C, como codeblocks, e salve-o com uma extensão .c
Compile e execute-o.
Depois de executar com êxito, vá para a pasta em que você instalou seu compilador gcc e dê o
seguinte comando para obter um arquivo '.s' do arquivo '.c'
C: \ gcc> gcc -S caminho completo do arquivo C ENTER
Um comando de exemplo (como no meu caso)
C: \ gcc> gcc -SD: \ Aa_C_Certified \ alternate_letters.c
Isso gera um arquivo '.s' do arquivo '.c' original
4) Depois disso, digite o seguinte comando
C; \ gcc> cpp filename.s ENTER
Comando de exemplo (como no meu caso)
C; \ gcc> cpp alternate_letters.s
Isso imprimirá / produzirá todo o código da linguagem Assembly do seu programa C.
fonte
Use "-S" como uma opção. Ele exibe a saída da montagem no terminal.
fonte
gcc foo.c -masm=intel -fverbose-asm -O3 -S -o- |less
.-S
por conta própria criafoo.s
.Recentemente, eu queria conhecer a montagem de cada função em um programa,
foi assim que eu fiz.
fonte
Aqui está uma solução para C usando o gcc:
Aqui, a primeira parte armazena a saída de montagem do programa no mesmo nome de arquivo que o Programa, mas com uma extensão .s alterada , você pode abri-lo como qualquer arquivo de texto normal.
A segunda parte aqui compila seu programa para uso real e gera um executável para o seu programa com um nome de arquivo especificado.
O program.c usado acima é o nome do seu programa e a saída é o nome do executável que você deseja gerar.
BTW É o meu primeiro post no StackOverFlow: -}
fonte