Os recursos do gdb mais adequados para linguagem de montagem serão ilustrados a seguir via exemplos:
- Compile seu programa com o script gcc.sh (ele inclui informações para o gdb:
no caso do assembler essas informações são endereços associados a rótulos de instruções, de dados e da
numeração das linhas do código fonte acrescentadas pelo gdb e que podem ser usadas para identificar breakpoints.
- Dispare o qemu (qemu-arm -g num-porta-tcp nome-executavel) ou via script qemu.sh
e noutra janela terminal o gdb através do comando: ../gdb.sh nome-do-executável
- Coloque um breakpoint na função de entrada main (ou outra qualquer): b main
ou breakpoint main.
Obs: (i) a 1a letra de cada comando é em geral suficiente;
(ii) breakpoints são numerados a partir de 1.
- Dispare a execução: o comando c vai parar no breakpoint main.
- Exiba o programa fonte com as linhas numeradas: l ou list ou list num-linha ou list rotulo
(pressionando "Enter" repete o último comando, no caso exibe mais linhas)
- Se preciso coloque breakpoints adicionais: b debug (insere breakpoint
na entrada da rotina debug) ou: b 26 (insere breakpoint na instrução da linha 26)
- Para executar a próxima instrução: s "Enter" ou "step "Enter"".
- Para executar a próxima instrução sem entrar em subrotinas: n "Enter" (ou next "Enter")
(pressionando de novo "Enter" executa a próxima instrução e assim, sucessivamente)
- Para continuar a execução até o próximo breakpoint ou fim do programa:
c "Enter" (ou continue "Enter")
- Para reiniciar o programa: j main (ou desviar a execução para um rotulo/linha j rotulo/linha)
- f ou where: mostra a linha corrente de execução; a linha corrente
decompilada também pode ser exibida quando um breakpoint é atingido via comando: display/i $pc
- Para sair do gdb: q (ou quit, seguido de "y")
- Para exibir um ou mais registradores:
i r r0 - ou info registers r0: exibe r0 em hexa e decimal
i r r0 r1 r2 r3 - exibe r0 r1 r2 e r3 em hexa e decimal
i r - ou info registers: exibe todos os registradores + registrador de estado cpsr
- Para exibir um registrador (ou variável) em hexa, decimal, binário ou ascii:
p/x $r0 - ou "print/x $r0" exibe r0 em hexa, observe ser requerido o "$"
p/d $r1 - exibe r1 em decimal
p/t $r2 - exibe r2 em binário
p/c $r3 - exibe r3 em ascii
p/x myword - exibe o valor de "myword" (definida na área de dados)
- Para mudar o conteúdo de um registrador ou de uma variável na área de dados:
p $r3 = 0xff
p myword = 10
-
Exibindo posições de memória através do comando: x[/nfu] addr
n: número de posições a serem exibidas (default 1).
f: caracter de formatação (padrão printf): x(default), u, d, c, t (binário), s (string), i (instrução)
b: unidade a ser exibida: b (bytes), h (dois bytes), w (palavra, 4 bytes, default)
Exemplos:
Suponha que msg e oddnum foram definidos assim:
msg: .asciz "Hello World!\n"
oddnum: .word 3,5,7,9,11,13,15,17
e que r0 foi carregado com o endereço do vetor msg:
ldr r0,=msg
x/s $r0 - exibe "Hello World!"
x/s &msg:- exibe "Hello World!"
x/12cb &msg - exibe cada um dos 12 caracteres da cadeia "Hello World!"
x/12xb &msg - exibe 12 bytes com os valores da codificação Ascii dos caracteres em msg!
x/6dw &oddnum - exibe 3, 5, 7, 9, 11, 13 (em 2 linhas)
x/i $pc - exibe o código da istrução corrente (apontada pelo pc)
x/5i $pc - exibe o código das 5 instruções a partir da apontada pelo pc
- Para exibir os breakpoints correntes: info b ou i b
- Para remover o breakpoint 2: d 2 (ou delete breakpoint 2)
- Breakpoint condicional: parar no breakpoint 2 somente se r1=4: condition 2 $r1==4
ou, ao criar o breakpoint: break 26 if $r1==4
- Para não exibir as próximas 4 ocorrências do breakpoint 2: ignore 2 4
- Para incluir um registrador (ou variável) na "lista de display" e exibir seu valor
quando um breakpoint é atingido (inclusive na execução "passo a passo").
Obs: muito útil dentro de um laço:
display $r0 - exibe r0 quando o programa para num breakpoint
display/x $r1 - exibe r1 em hexa quando o programa para num breakpoint
display myword - ao parar num breakpoint exibe o conteúdo do dado cujo rótulo é "myword"
display - exibe o conteúdo da "lista de display" (nesse caso,r0, r1 e myword)
- Para remover um registrador (ou variável) da "lista de display":
undisplay n - remove o display de número n
undisplay - remove toda a lista de display caso responda "y"