um pequeno tutorial - IC

Propaganda
Apresentação da infraestrutura ARM para MC404
Divino César S. Lucas
12 de abril de 2013
1
Conectando na infraestrutura ARM do IC via ssh
Este documento descreve como se conectar a uma das três máquinas ARM do laboratório do IC-3.
Para ter acesso à infraestrutura, você deve estar em um dos computadores do IC-3 ou, se estiver
em casa, conectar-se ao IC-3 via SSH. Exemplo:
eu@meupc$ ssh ssh.students.ic.unicamp.br -l ra99999
Uma vez em um computador do IC-3, você pode acessar um computador ARM via SSH usando
um dos três endereços abaixo. Note que os dados de login são os mesmos que você utilizou para se
logar nos computadores do IC-3.
arm1.lab.ic.unicamp.br
arm2.lab.ic.unicamp.br
arm3.lab.ic.unicamp.br
Exemplo:
-bash-4.2$ ssh arm1.lab.ic.unicamp.br -l ra99999
Observação: Como você estará se conectando em uma máquina do mesmo domínio (lab.ic.unicamp.br),
você pode omitir o domínio quando estiver se conectando. Então, ssh arm1 basta.
Uma vez conectado a uma máquina ARM, você contará com uma pasta home particular sua
para armazenar seus arquivos, mas que não é o mesmo home do seu Linux do IC-3. Para acessar o
seu home ARM a partir de um computador normal do IC-3, acesse a pasta ~mc404/homes/ra99999.
Trabalhando remotamente
Para testar seus projetos na máquina ARM, você precisará trabalhar via SSH sem acesso físico à
máquina1 . Portanto será importante que você se acostume a trabalhar usando apenas o console e
editores de texto que não usam interface gráfica (vi, vim, emacs, nano, etc). Vale lembrar alguns
truques que facilitam a vida:
• Caso esteja editando um arquivo ou executando um programa no console e deseja interrompêlo temporariamente, digamos, para compilar o programa, você pode usar a tecla Ctrl+Z. Isto
irá suspender o processo do editor (ou o programa que você estiver executando) e você voltará
à linha de comando, livre para rodar outros programas. Para voltar ao programa suspenso,
digite na linha de comando fg 1. Se você tem vários programas suspensos, pode precisar
outros números além de 1.
1 Se
você tem curiosidade pra saber como é a máquina ARM fisicamente, google imx53 e vá em imagens.
1
• Uma conexão por SSH pode cair devido a diversos motivos e problemas de rede, principalmente
se você estiver em sua casa. Se isso ocorrer, todos os programas (possivelmente editores de
texto trabalhando no projeto) serão fechados automaticamente. Para evitar que você perca
a sua sessão devido a uma desconexão, utilize o programa screen. Ao digitar screen no
console, você irá abrir um outro shell. Este shell é seguro e, caso você seja desconectado, você
pode reconectar e voltar à sua sessão digitando apenas screen -r. Dentro do screen você
pode ainda, administrar várias janelas diferentes de terminais. Consule a ajuda do programa
digitando ’Ctrl+A’ seguido por ’ ?’ (todos os comandos do screen começam com ’Ctrl+A’).
• Se você quer evitar ao máximo usar o terminal, você pode editar os arquivos fonte de seu
projeto do computador do IC-3 e salvá-los na pasta ~mc404/homes/ra99999 (seu RA), que é
o seu home quando você loga via SSH na máquina ARM.
• Finalmente, você pode ainda utilizar o comando scp para enviar arquivos entre duas maquinas.
Para enviar o arquivo teste.as da sua maquina local para seu diretorio home do IC-3, voce
pode utilizar o seguinte comando: scp teste.as [email protected]:/~
onde ra999999 deve ser substituido pelo seu RA. De forma similar para baixar um arquivo
teste2.as do seu diretorio home do IC-3 para a maquina local voce pode digitar o este
comando: scp [email protected]:~/teste.as . .
2
Exemplo de código em linguagem assembly ARM
O exemplo de código na Listagem 1 mostra um program em linguagem assembly do ARM que utiliza
as funções printf e scanf da biblioteca padrão C (libc) para pedir ao usuário que informe um valor
inteiro e escrever de volta o valor lido na tela do usuário.
Listing 1: Exemplo de código em linguagem ARM assembly
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.globl main
.extern scanf
.extern printf
.data
printf1:
printf2:
scanf1:
numero:
.asciz "Digite um numero: "
.asciz "Valor lido: %d\n"
.asciz "%d"
.word 0
.text
.align 4
main:
push {ip, lr}
ldr r0, =printf1
bl printf
ldr r1, =numero
ldr r0, =scanf1
bl scanf
ldr r0, =printf2
ldr r1, =numero
ldr r1, [r1]
bl printf
mov r0, #0
pop {ip, pc}
2
As três primeiras linhas deste arquivo dizem ao montador para considerar que a função main (que
será definida logo mais neste arquivo) tem visibilidade global, ou seja funções definidas em outros
arquivos podem chamar a função main. Além disso estas linhas também avisam ao montador o
interesse de utilizar as funções scanf e printf que foram definidas em outro arquivo (no caso dentro
da biblioteca padrão do C).
A linha 5, diretiva .data, diz ao montador que a partir desse ponto segue uma serie de definições
em relação a alocação de dados. Ou seja, definição de variáveis. As linhas 6, 7 e 8 criam três variáveis
(rótulos) com os nomes printf1, printf2 e scanf1 que conterão sequencias de bytes no padrão asci.
Estas variáveis são inicializadas com os valores "Digite um numero: ", "Valor lido: %d
n"e "%d", respectivamente. Note que como declaramos o tipo das variáveis como .asciz o montador
já colocará automaticamente o terminador de cadeia de caracteres ’\0’ no final do conteúdo da
variável. Estas variáveis, como você já deve ter imaginado, armazenam a string de formatação que
serão utilizadas pelas funções printf e scanf no exemplo. A linha 9 cria uma variável chamada
"numero"com o tamanho de uma palavra (.word == 4 bytes) e inicializa o conteúdo para o valor
zero. Esta variável guardará o valor que o usuário informar para o programa.
A diretiva de montagem da linha 11, .text, diz ao montador que a partir desse ponto segue as
definições das instruções (funções) que o programa poderá executar. A linha 12 diz ao montador
para alinhar a emissão do mapa de memória do código gerado, em 4 bytes. A linha 14 define um
rótulo chamado "main". Em geral linguagens de montagem representam funções utilizando rótulos,
ou seja, dando nome para trechos de código. Em seguida quando for necessário fazer a invocação
de uma função o programador utiliza uma instrução para fazer um salto para o endereço daquele
rótulo. Portanto, nesta linha inicia-se a definição da função "main".
A linha 15 é o que chamamos de prólogo da função e basicamente ela serve para garantir que o
código que invocou a função atual (função atual seria a main) possa continuar a execução a partir
do ponto onde ele parou. Não se preocupe com esse ponto por agora, isso será melhor esclarecido
posteriormente.
Para fazer a invocação de funções em linguagem de montagem você deve, em geral, fazer um
desvio para o rótulo definido como o nome da função. Se a função sendo chamada recebe algum
parâmetro os valores deverão ser passados utilizando registradores. Por exemplo, a linha 17 coloca
o endereço do rótulo printf1 dentro do registrador r0 e em seguida invoca a execução da função
printf. Nesse ponto o programa irá imprimir a mensagem "Digite um numero: "na tela do usuário
e voltar a executar o programa (função main) a partir da linha 20. Na linha 20 começamos a fazer
a invocação da função scanf. A função scanf recebe, neste caso, dois parâmetros. O primeiro deles,
que deve ser armazenado no registrador r0, é a string de formatação utilizada ("%d") e o segundo
parâmetro é o endereco de memória onde deve ser armazenado o valor lido, que deve ser armazenado
em r1 (=numero). A linha 22 invoca a execução da função scanf. Após o usuário informar o valor
o programa continuará a execução a partir da linha 24.
Na linha 24 começamos a preparar a invocação da função printf para informar ao usuário o valor
que acabamos de ler. Novamente os parâmetros para a função devem ser passados nos registradores
r0, r1, etc. (até r3). No registrador r0 novamente colocamos o endereço da string de formatação.
Na linha 25 carregamos no registrador r1 o endereço (=numero) da variável numero e na linha 26
carregamos o conteúdo do valor armazenado no endereço de memória armazenado no registrador
r1. Por fim, na linha 27 invocamos a função printf.
A linha 29 e 30 move a constante 0 (zero em decimal) para o registrador r0 e prepara para voltar
a executar o código que invocou a função main. Lembre-se que um programa em linguagem C,
em geral possui como ultima linha da função main a instrução return 0 ou exit(0). Este ponto
também será descrito em maiores detalhes em uma aula/laboratório futuro.
3
Como compilar seu programa em linguagem assembly
Para compilar o seu programa em linguagem assembly do arm você tem duas opções. Você pode
utilizar um montador (vamos utilizar o GNU AS) e depois o GCC para que ele faa̧ a linkagem
autoamticamente para você ou você pode utilizar o GNU AS e em seguida o GNU LD. Vejamos
como fazer cada caso. O primeiro passo é fazer a montagem do arquivo, para isso considere que o
3
código em linguagem de montagem foi escrito e salvo em um arquivo chamado exemplo1.as e que o
resultado do processo de montagem será armazenado no arquivo exemplo1.o.
Primeiro geramos o arquivo montado (arquivo objeto ou .o):
ra999999@arm1:~$ as exemplo1.as -o exemplo1.o
e em seguida criamos o arquivo executável utilizando o GNU linker (digite este comando em um
linha, ou quebre linha no lugar indicado por uma barra invertida "\"):
ra999999@arm1:~$ ld -dynamic-linker /lib/ld-linux.so.3 /usr/lib/crt1.o \
/usr/lib/crti.o -L/usr/lib exemplo1.o -lc /usr/lib/crtn.o -o exemplo1
ou o GCC:
ra999999@arm1:~$ gcc exemplo1.o -o exemplo1
Note que o arquivo executável gerado será chamado de exemplo1. Note também que o GCC irá
basicamente executar o mesmo comando que você digitaria no exemplo.
Você pode executar o programa digitando:
ra999999@arm1:~$ ./exemplo1
Digite um numero: 2001
Valor lido: 2001
ra999999@arm1:~$
4
Referências sobre ARM
• Cartão de referência rápida para as instruções ARM: http://infocenter.arm.com/help/
topic/com.arm.doc.qrc0001m/QRC0001_UAL.pdf (ignore as instruções que só são suportadas
em versões específicas do ARM, como Thumb, Thumb2, v6 e v7)
• Referência da arquitetura ARMv5, utilizada no simulador da disciplina: http://www.scss.
tcd.ie/~waldroj/3d1/arm_arm.pdf (Capítulo A4 descreve instrução por instrução)
• Infocenter ARM: http://infocenter.arm.com/help/index.jsp
• Site com bastante material sobre linguagem de montagem ARM: http://www.coranac.com/
tonc/text/asm.htm (ignorar a parte de Thumb).
• Manual do GNU assembler, o montador utilizado: http://sourceware.org/binutils/docs/
as/
• Manual do GNU debugger (o gdb, depurador utilizado): http://sourceware.org/gdb/current/
onlinedocs/gdb/
4
Download