Modulo VI Escrevendo cdigo em Linguagem de Montagem

  • Slides: 47
Download presentation
Modulo VI Escrevendo código em Linguagem de Montagem (Assembly)

Modulo VI Escrevendo código em Linguagem de Montagem (Assembly)

Conjunto de Instruções § Arquitetura RISC § Reduced Instruction Set Computer § Operação com

Conjunto de Instruções § Arquitetura RISC § Reduced Instruction Set Computer § Operação com dados se dão nos registradores, nunca na memória § Instruções de carga (Load) de dados da memória em registradores § Instruções de armazenagem (Store) de dados de registradores para a memória

Formato Típico das Instruções Assembly MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § Itens entre { } são

Formato Típico das Instruções Assembly MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § Itens entre { } são opcionais § Itens entre < > são uma breve descrição sobre um tipo de valor que será passado pelo programador § Muitas instruções podem ser executadas condicionalmente § Isso pode evitar os desvios (branch). Desvios podem prejudicar o desempenho de arquiteturas com muitos níveis no pipeline

Formato Típico das Instruções Assembly MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § Muitas instruções podem alterar ou

Formato Típico das Instruções Assembly MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § Muitas instruções podem alterar ou não os bits de estados dependendo da forma da instrução § Facilita a comparação de dados (pos, neg, zero. . ) § Operações aritméticas em dados não relacionados podem ocorrer durante uma pendência, sem alterar os bits de estados § O último operando é um operador de deslocamento, outros são registradores.

Formato Típico das Instruções Assembly Em C if (a > b) c = a;

Formato Típico das Instruções Assembly Em C if (a > b) c = a; else c = b; Considere que R 0, R 1 e R 2 estão carregados com os valores de a, b e c, respectivamente Em Assembly cmp ble mov b R 0, R 1 L 1 R 2, R 0 L 2 mov R 2, R 1 L 1: L 2: cmp R 0, R 1 movgt R 2, R 0 movle R 2, R 1 ou

Formato do operador_de_deslocamento MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § #<immediate> - Valor pode receber somente certos

Formato do operador_de_deslocamento MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § #<immediate> - Valor pode receber somente certos valores § <Rm> - Conteúdo de Rm § <Rm>, LSL #<shift_imm> - Conteúdo de Rm deslocado logicamente à esquerda por um valor imediato, exemplo: R 2, LSL #5 § <Rm>, LSL <Rs> - Conteúdo de Rm é deslocado logicamente à esquerda por um valor contido em Rs

Formato do operador_de_deslocamento MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § <Rm>, LSR #<shift_imm> - Conteúdo de Rm

Formato do operador_de_deslocamento MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § <Rm>, LSR #<shift_imm> - Conteúdo de Rm é deslocado logicamente à direita por um valor imediato § <Rm>, LSR <Rs> - Conteúdo de Rm é deslocado logicamente à direita por um valor contido em Rs § <Rm>, ASR #<shift_imm> - Conteúdo de Rm é deslocado para direita aritmeticamente por um valor imediato, com ou sem sinal § <Rm>, ASR <Rs> - Conteúdo de Rm é deslocado aritmeticamente à direita por um valor contido em Rs, com ou sem sinal

Formato do operador_de_deslocamento MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § <Rm>, ROR #<shift_imm> - Conteúdo de Rm

Formato do operador_de_deslocamento MOV{<cond>}{S} <Rd>, <operador_de_deslocamento> § <Rm>, ROR #<shift_imm> - Conteúdo de Rm é rotacionado à direita por um valor imediato § <Rm>, ROR <Rs> - Conteúdo de Rm é rotacionado à direita por uma quantidade Rs § <Rm>, RRX – Conteúdo de Rm é deslocado um bit à direita, o bit de Carry é deslocado para alto e o bit 0 de Rm é colocado no bit de carry As operações de deslocamento não mudam o conteúdo de Rm, apenas o valor do resultado usado como o operando

Operador de deslocamento: Formas do ROR 4 bits Imediato 8 bits imediato § Pode

Operador de deslocamento: Formas do ROR 4 bits Imediato 8 bits imediato § Pode rotacionar à direita um valor imediato de 8 bits por qualquer número par de bits § O campo de rotação tem seu valor multiplicado por dois, dessas forma é possível deslocar até 30 bits § Apenas valores especiais de constantes podem ser representados § 0 x. FF (possível) § 0 x. FF 0 (possível) § 0 x. FF 1 (Não) § 0 x 1 FE (Não) § Pode ser necessário formar constantes em mais de uma etapa, por exemplo: 0 x. FFFF § Evite, se for possível, criar espaços para dados constantes

Formato do operador_de_deslocamento #<immediate> mov add mov ldr R 0, #127 R 0, R

Formato do operador_de_deslocamento #<immediate> mov add mov ldr R 0, #127 R 0, R 1, #0 x 7 f R 2, #125952 R 2, =125951 ; R 0 = 127 ; R 0 = R 1 + 127 ; R 2 = 125952 = 123*4*4*4 ; R 2 = 125951 = 123*4*4*4 - 1 LDR R 2, =125951 é uma instrução que é desdobrada pelo montador em um carregamento (LDR) de uma posição de memória com o valor 125951 mov add mov R 0, #257 R 0, R 1, #0 x 101 R 2, #125951 ; erro! ; 125951 = 123*4*4*4 -1 erro!

Formato típico de uma instrução LDR/STR LDR{<cond>} <Rd>, <modo_de_endereçamento> § LDR - Usado para

Formato típico de uma instrução LDR/STR LDR{<cond>} <Rd>, <modo_de_endereçamento> § LDR - Usado para carregar um valor da memória para um registrador § STR - Usado para armazenar o valor em um registrador na memória § Pode ser executado condicionalmente § Não altera os bits de estados CSPR (Current Status Program Register) § Usa modo_de_endereçamento para endereçar o dado na memória

Formato do modo_de_endereçamento LDR{<cond>} <Rd>, <modo_de_endereçamento> § [<Rn>, #+/-<offset_12>] – O endereço é o

Formato do modo_de_endereçamento LDR{<cond>} <Rd>, <modo_de_endereçamento> § [<Rn>, #+/-<offset_12>] – O endereço é o conteúdo de Rn mais ou menos o offset_12 de 12 bits com sinal § [<Rn>, +/-<Rm>] – Endereço é o conteúdo de Rm mais ou menos o conteúdo de Rm § [<Rn>, +/-<Rm>, <shift> <shift_imm>] – O endereço é o conteúdo de Rn mais ou menos conteúdo de Rm deslocado por um operador <shift> pelo número de bits em <shift_imm> § [<Rn>, #+/-<offset_12>]! – O endereço é o conteúdo de Rn mais ou menos um offset_12 de 12 bits com sinal, endereço é escrito de volta para Rn (pré-indexado)

Formato do modo_de_endereçamento LDR{<cond>} <Rd>, <modo_de_endereçamento> § [<Rn>, +/- <Rm>]! – O endereço é

Formato do modo_de_endereçamento LDR{<cond>} <Rd>, <modo_de_endereçamento> § [<Rn>, +/- <Rm>]! – O endereço é o conteúdo de Rn mais ou menos o conteúdo de Rm, endereço é escrito de volta para Rn (pré-indexado) § [<Rn>, +/-<Rm>, <shift> <shift_imm>]! – O endereço é o conteúdo de Rn mais ou menos o conteúdo de Rm deslocado por um operador <shift> pelo número de bits em <shift_imm>, o endereço é escrito de volta para Rn (pré-indexado) § [<Rn>], #+/-<offset_12> - O endereço é o conteúdo de Rn, o valor offset_12 de 12 bits com sinal é adicionado a Rn, escrito de volta para Rn (pós-indexado)

Formato do modo_de_endereçamento LDR{<cond>} <Rd>, <modo_de_endereçamento> § [<Rn>] +/-<Rm> - O endereço é o

Formato do modo_de_endereçamento LDR{<cond>} <Rd>, <modo_de_endereçamento> § [<Rn>] +/-<Rm> - O endereço é o conteúdo de Rn, Rm é adicionado ou subtraído de Rn, escrito de volta para Rn (pós-indexado) § [<Rn>] +/-<Rm>, <shift> <shift_imm> - O endereço é o conteúdo de Rn, conteúdo de Rm é deslocado operador <shift> pelo número de bits em <shift_imm> o valor é adicionado ou subtraído de Rn (pósindexado)

Formato do modo_de_endereçamento ; Coloca o valor apontado por R 0 em R 1

Formato do modo_de_endereçamento ; Coloca o valor apontado por R 0 em R 1 e incrementa R 0 para ; indicar o próximo inteiro de 32 bits ldr R 1, [R 0], #4 ; Incrementa o conteúdo de R 2 fazendo-o apontar para o próximo ; inteiro de 32 bits, esse inteiro é atribuído para R 3 ldr R 3, [R 2, #4]! ; O endereço é o valor R 5 deslocado 4 bytes, o resultado aponta ; para o próximo inteiro de 32 bits, esse inteiro é atribuído para R 4. ; R 5 não é alterado ldr R 4, [R 5, #4] ; O mesmo endereçamento pode ser usado pela instrução STR str R 1, [R 0], #4 str R 3, [R 2, #4]! str R 4, [R 5, #4]

Instruções Dignas de Atenção § BIC – Bit Clear § desliga os bits indicados

Instruções Dignas de Atenção § BIC – Bit Clear § desliga os bits indicados na mascara § CLZ – Count Leading Zeros § ideal para determinar o número de bits necessários para representar um número § LDM/STM – Load/Store Multiple § usado para salvar e recuperar registradores na pilha § especialmente útil: STMDB, LDMDB § RSB – Reverse Substract Operand Order § permitem que o operador_de_deslocamento seja subtraídos do registrador

Registradores § R 0 até R 3 – Propósito geral, salvos pelo chamador da

Registradores § R 0 até R 3 – Propósito geral, salvos pelo chamador da rotina § R 4 até R 11 – Propósito geral, salvos pela rotina chamada § R 12 – Frame Pointer (algumas vezes) § R 13 – Stack Pointer (SP – Apontador da Pilha) § R 14 – Link Register (LR) § R 15 – Program Counter (PC) § CSPR – Currente Status Program Register, contém a sinalização de overflow, zero, underflow, . . .

Registradores § Pode ser desejável dar nomes mais sugestivos aos registradores, para isso usa-se

Registradores § Pode ser desejável dar nomes mais sugestivos aos registradores, para isso usa-se a diretiva RN contador RN R 0 resultado RN R 1 § Pode ser desejável também colocar nomes as constantes literais (valores imediatos) mascara EQU 0 x 000000 ff minimo EQU 0 maximo EQU 32767 § Usando: mov contador, #minimo cmp contador, #maximo

Convenção da Pilha § A Pilha cresce “para baixo” § Dados colocados na pilha

Convenção da Pilha § A Pilha cresce “para baixo” § Dados colocados na pilha têm endereços de memória menores que os dados colocados previamente § O armazenamento dos dados na pilha é pré-decrementado. § Ponteiro da pilha aponta para o último elemento colocado nela. Topo SP SP + 4 SP + 8 SP + 12 SP + 16 Crescimento da pilha

Assembly: Estrutura do Arquivo ; cpenable. asm Comentários se iniciam com ; AREA CPENABLE,

Assembly: Estrutura do Arquivo ; cpenable. asm Comentários se iniciam com ; AREA CPENABLE, CODE, READONLY EXPORT é usado para exportar o nome da função para uso externo Rótulos começam na coluna 1, PROC é uma diretiva usada para identificar funções Informações sobre a área que será usada ; CP 15 Routines EXPORT Get. CP 0 Enable ; Retorna valor escrito em r 0 Get. CP 0 Enable PROC MRC p 15, 0 x 0, r 0, c 15, c 1, 0 x 0 mov pc, lr ENDP END indica onde o arquivo acaba ENDP mostra onde a função acaba

Chamando um Módulo em Assembly § Por convenção no C para o ARM os

Chamando um Módulo em Assembly § Por convenção no C para o ARM os quatro primeiros parâmetros são passados nos registradores R 0 – R 3 § O restante é passado na pilha, da esquerda para a direita, sendo que o parâmetro mais à esquerda está no topo da pilha § O registrador Stack Pointer aponta para o 5º parâmetro se ele estiver presente § Ajustes são necessários se a função não for uma função folha § Para funções folha, podemos usar o stack pointer tanto para pilha quanto para frame pointer § Para funções não folha o stack pointer será ajustado, ou usa-se R 12 como frame pointer ou ajusta-se as referências das variáveis colocadas na pilha pelo chamador

Exemplo da Manipulação de Parâmetros em uma função Asm Parâmetros de a-d estão em

Exemplo da Manipulação de Parâmetros em uma função Asm Parâmetros de a-d estão em R 0 -R 3, respectivamente O parâmetro e é o mais baixo na pilha, o ponteiro da pilha stack pointer aponta para ele. Agora, ele está em R 4. ; parms. asm AREA PARMS, CODE, READONLY ; Routines Salva os EXPORT Parms ; Parms (a, b, c, d, e, f) registradores R 4 Parms PROC e R 5 na pilha stmdb sp, {r 4, r 5} ldr r 4, [sp] ldr r 5, [sp, #4] Parâmetro f é o ; o código vai aqui ldmdb sp, {r 4, r 5} próximo na pilha, mov pc, lr assim, stack ENDP pointer+4 é END atribuido para R 5

Retornando da Função em Assembly Restaura os valores de R 4 e R 5,

Retornando da Função em Assembly Restaura os valores de R 4 e R 5, ajuste o stack pointer se necessário Restaura o PC com o conteúdo do Link Register. Lembre-se de salvar o conteúdo de LR se esta função não for uma função folha ; count. asm AREA PARMS, CODE, READONLY ; Routines EXPORT Count PROC stmdb sp, {r 4, r 5} mov r 4, #0 mov r 5, #0 x. F 8 loop Valores de add r 4, #1 retorno da cmp r 4, r 5 blt loop função são passados em R 0 mov r 0, r 4 ldmdb sp, {r 4, r 5} mov pc, lr ENDP END

Exemplo da Manipulação de Parâmetros em uma função Asm Soma os dois parâmetros e

Exemplo da Manipulação de Parâmetros em uma função Asm Soma os dois parâmetros e retorna o resultado pela função ; soma 2. asm AREA SOMA, CODE, READONLY ; Routinas EXPORT soma 2 ; int soma 2(int, int) soma 2 PROC add R 0, R 1 ; R 0 = R 0 + R 1 mov pc, lr ENDP END

Retornando da Função em Assembly Soma os seis parâmetros e retorna o resultado pela

Retornando da Função em Assembly Soma os seis parâmetros e retorna o resultado pela função ; soma 6. asm AREA SOMA, CODE, READONLY ; Routinas EXPORT soma 6 ; int soma 6(int, int, int) soma 6 PROC stmdb add add ldr add ldmdb mov ENDP END SP, {R 4, R 5} R 0, R 1, R 2, R 3 R 0, R 1 R 4, [SP] R 5, [SP, #4] R 1, R 4, R 5 R 0, R 1 SP, {R 4, R 5} PC, LR

Retornando da Função em Assembly Soma os seis parâmetros e retorna o resultado no

Retornando da Função em Assembly Soma os seis parâmetros e retorna o resultado no sétimo parâmetro Observe que os registradores R 4 e R 5 não estão mais sendo usados. ; soma 7. asm AREA SOMA, CODE, READONLY ; Routinas EXPORT soma 7 ; int soma 7(int, int, int *) soma 7 PROC add add ldr str mov ENDP END R 0, R 1, R 2, R 3 R 0, R 1, [SP] R 2, [SP, #4] R 1, R 2 R 0, R 1, [SP, #8] R 0, [R 1] PC, LR

Retornando da Função em Assembly AREA SOMA, CODE, READONLY EXPORT soma 7 ; int

Retornando da Função em Assembly AREA SOMA, CODE, READONLY EXPORT soma 7 ; int soma 7(int, short int, short int *) soma 7 Soma os seis parâmetros e retorna o resultado no sétimo parâmetro PROC stmdb add add ldrh add ldr strh ldmdb mov ENDP END SP, {R 4, R 5, R 6} R 0, R 1, R 2, R 3 R 0, R 1 R 4, [SP] R 5, [SP, #4] R 1, R 4, R 5 R 0, R 1 R 5, [SP, #8] R 0, [R 5] SP, {R 4, R 5, R 6} PC, LR Observe que os três últimos parâmetros têm 16 bits cada

Passando vetor parâmetro em Assembly Retorna o endereço de um elemento em um vetor

Passando vetor parâmetro em Assembly Retorna o endereço de um elemento em um vetor int vet[10]; int p*; int * procura(int v[ ], int x) { int i; for (i=0; i<10; i++) if (v[i]==x) return &v[i]; return NULL; } void main(void) {. . . p=procura(vet, 1234); . . } procura AREA VETOR, CODE, READONLY EXPORT procura PROC mov R 2, #0 laco ldr cmp addeq moveq add cmp movge b ENDP END R 3, [R 0, R 2, LSL #2] R 1, R 3 R 0, R 2 PC, LR ; return &v[i] R 2, #10 R 0, #0 ; return NULL PC, LR laco

Passando ponteiro por parâmetro em Assembly Iniciação de uma lista linear simplesmente encadeada typedef

Passando ponteiro por parâmetro em Assembly Iniciação de uma lista linear simplesmente encadeada typedef struct s_no { long dado; struct s_no *prox; } no; no *lista; void inicia. Lista(no *d=NULL; } void main(void) {. . . inicia. Lista(&lista). . . } **d) { &lista, d R 0 lista, *d [R 0] ? antes *d [R 0] depois AREA LISTA, CODE, READONLY EXPORT inicia. Lista PROC mov R 1, #0 str R 1, [R 0] mov PC, LR ENDP END

Exportando uma função Assembly de uma DLL AREA. drectve DRECTVE DCB “-export: Count” DCB

Exportando uma função Assembly de uma DLL AREA. drectve DRECTVE DCB “-export: Count” DCB é usado para definir uma string na qual contém diretivas para o ligador ajustar o código como sendo uma exportação. dll A diretiva deve estar na área DRECTVE em uma seção chamada. drectve ; count. asm AREA COUNT, CODE, READONLY ; Rotinas EXPORT Count PROC stmdb sp, {r 4, r 5} mov r 4, #0 mov r 5, #0 x. F 8 loop add r 4, #1 cmp r 4, r 5 blt loop mov r 0, r 4 ldmdb sp, {r 4, r 5} mov pc, lr ENDP END

Usando Assembly na IDE § Clique na pasta Source files, adicione um arquivo. asm

Usando Assembly na IDE § Clique na pasta Source files, adicione um arquivo. asm no projeto § Selecione ‘All Files’ na caixa de diálogo, assim você pode ver os arquivos. asm § Clique com o botão direito no arquivo ASM na pasta source do projeto, vá para settings § Na aba Custom Build § Digite armasm para chamar o montador § Utilize a opção xscale cpu se estiver chamando mnemônicos xscale (armasm –cpu xscale) § Use o caminho relativo ao arquivo como o apresentado no arquivo de entrada (input File) § Use apenas o nome do arquivo com a extensão. obj como saída

Melhorando as Dependências Usando LDR add r 1, r 2, r 3 ldr r

Melhorando as Dependências Usando LDR add r 1, r 2, r 3 ldr r 0, [r 5] add r 6, r 0, r 1 sub r 8, r 2, r 3 mul r 9, r 2, r 3 ldr r 0, [r 5] add r 1, r 2, r 3 sub r 8, r 2, r 3 add r 6, r 0, r 1 mul r 9, r 2, r 3 Com o dado na Cache, três ciclos são necessários para a transferência do valor ao registrador Como o dado pode não estar na cache, o LDR deve ser colocado o mais cedo possível antes do ponto de utilização

Instruções LDRD/STRD § Lê e armazena 64 bits em dois registradores § O Endereço

Instruções LDRD/STRD § Lê e armazena 64 bits em dois registradores § O Endereço deve estar alinhado em 8 bytes (64 bits) § Os registradores devem ser os pares: § R 0, R 1; R 2, R 3; R 4, R 5; . . . add sub ldrd orr mul r 6, r 5, r 0, r 8, r 7, r 6, [r 3] r 1, r 0, r 8 r 9 #0 xf r 7 ldrd add sub mul orr r 0, r 6, r 5, r 7, r 8, [r 3] r 7, r 6, r 0, r 1, r 8 r 9 r 7 #0 xf LDRD necessita de 3 ciclos para disponibilizar os dados nos registradores

Instruções LDM/STM § 2 a 20 ciclos para disponibilizar os valores nos registradores, §

Instruções LDM/STM § 2 a 20 ciclos para disponibilizar os valores nos registradores, § depende do número de registradores envolvidos na troca de dados § A latência é de 2 ciclos mais 1 ciclo por registrador envolvido § A próxima instrução é atrasada um ciclo (com ou sem dependências e acessos à memória)

Utilizando LDM ou LDRD § Soma de dois valores de 64 bits § r

Utilizando LDM ou LDRD § Soma de dois valores de 64 bits § r 0 endereço do primeiro valor § r 1 endereço do segundo valor ldm r 0, {r 2, r 3} ldm r 1, {r 4, r 5} adds r 0, r 2, r 4 adc r 1, r 3, r 5 ldrd r 2, [r 0] ldrd r 4, [r 1] adds r 0, r 2, r 4 adc r 1, r 3, r 5 Mais rápido para executar

Indo além do básico em Assembly § Estude o ARM (ARM Architecture Reference Manual),

Indo além do básico em Assembly § Estude o ARM (ARM Architecture Reference Manual), também disponível no formato pdf em www. arm. org § Estude o help do EVC++, tópico ARM Assembly § Compile seu código com a opção de disassembly ativada e veja o que o compilador gera: § Misture código C com assembly § Desligue as otimizações do compilador

Indo além do básico em Assembly: Use o e. VC++ Vá em Project Settings->

Indo além do básico em Assembly: Use o e. VC++ Vá em Project Settings-> C/C++ tab -> Selecione Listing Files Coloque List Assembly with Source

Quando e onde substituir o código por Assembly § Apenas em regiões do código

Quando e onde substituir o código por Assembly § Apenas em regiões do código críticas no desempenho § Para tirar maior proveito do pipeline do processador Intel® XScale™ § O número de variáveis envolvidas for grande § O compilador é incapaz de fazer um bom uso de muitos registradores § O compilador está armazenando valores locais em memória § Quando esses valores poderiam ser mantidos nos registradores § Há instruções muito melhores em Assembly para: § Melhor acesso a overflow § Melhor acesso a instruções DSP

Quando for escrever o código em Assembly § Utilize muitos comentários § Inclua o

Quando for escrever o código em Assembly § Utilize muitos comentários § Inclua o código em C, que o Assembly estiver substituindo, como comentário § Use as diretivas RN e EQU para dar nomes esclarecedores aos registradores e aos valores imediatos § Sempre salve e recupere os conteúdos Registradores usados pela função que faz a chamada se você os usa § Cuidado ao trabalhar com funções que não são do tipo folha § Salve o conteúdo de LR § Observe as alterações em SP

Quando for escrever o código em Assembly § Tome cuidado com o alinhamento de

Quando for escrever o código em Assembly § Tome cuidado com o alinhamento de dados § Para ler dados do tipo short em um vetor use as instruções LDRH ou LDRSH § Use STRH para escrever dados do tipo short em um vetor § Assim como com os tipos short, tenha certeza de estar usando LDRB para vetores de bytes § Desconsiderar essas instruções para dados do tipo short ou byte pode causar problemas de alinhamento de dados Erros de alinhamento em geral causam o travamento da máquina, deixando-o sem pistas do que pode ter dado errado com o seu programa

Otimizando Código em Assembly § Não armazena dados de volta a pilha § Mantenha

Otimizando Código em Assembly § Não armazena dados de volta a pilha § Mantenha as variáveis em registradores o máximo de tempo possível § Observe a tabela de latências § Ordene as instruções tendo em mente o tempo de latência de cada uma delas § Tente desenrolar o laço § Tente usar Pre. Load também em Assembly (Instrução PLD) § Lembre-se que algumas instruções aritméticas levam mais de 1 ciclo de clock § Não deixe de tirar proveito das instruções de execução condicional § Repita pequenos pedaços de código se isso conseguir evitar desvios (branches)

Modulo VI Técnicas de Otimização Considerações sobre o código Compilado

Modulo VI Técnicas de Otimização Considerações sobre o código Compilado

Evite o uso desnecessário de Shorts int Test(void) { short x, y; x =

Evite o uso desnecessário de Shorts int Test(void) { short x, y; x = 3; y = 4; Observe que o compilador realiza dois deslocamentos para estender o sinal do valor de Short. Sum para retornar o valor de Test. Perda de tempo! ; depois de retornar de Short. Sum mov r 1, r 0, lsl #16 mov r 0, r 1, #asr #16 mov pc, lr ENDP Short. Sum PROC ; start return Short. Sum(x, y); } mov r 0, lsl #16 mov r 2, r 0, asr #16 mov r 1, lsl #16 short Short. Sum(short a, short b) add r 0, r 2, r 1, asr #16 { mov r 2, r 0, lsl #16 return a+b; } Diversos mov’s para truncar e estender o sinal dos operandos e do resultado mov r 0, r 2, asr #16 mov pc, lr ; return ENDP

Corrija as suas variáveis shorts int Test(void) { int x, y; Se necessário manter

Corrija as suas variáveis shorts int Test(void) { int x, y; Se necessário manter o mesmo range de short, use cast ; Depois de retornar de Shot. Sum mov r 1, r 0, lsl #16 mov r 0, r 1, #asr #16 x = 3; mov pc, lr y = 4; ENDP return (short)Short. Sum(x, y); } Short. Sum PROC ; start add r 0, r 1 int Short. Sum(int a, int b) { mov pc, lr ; return a+b; } ENDP

Evite o Apelidamento de Variáveis [Aliasing of Variables] int Alias. Taken(int indx) { Trans.

Evite o Apelidamento de Variáveis [Aliasing of Variables] int Alias. Taken(int indx) { Trans. Index(&indx); indx += 5; indx += Displace. Index(indx); indx += Dither. Index(indx); return indx; } Já que usamos o endereço de indx, o compilador é conservador em mantê-lo em um registrador, causando vários acessos à memória ; Trans. Index(&indx) add r 0, sp, #8 bl Trans. Index ; indx += 5; ldr r 3, [sp, #8] add r 0, r 3, #5 str r 0, [sp, #8] ; indx += Displace. Index(indx); bl Displace. Index ; 00000028 mov r 3, r 0 ldr r 0, [sp, #8] add r 0, r 3 str r 0, [sp, #8] ; indx += Dither. Index(indx); bl Dither. Index ; 0000003 C mov r 3, r 0 ldr r 0, [sp, #8] add r 0, r 3

Aperfeiçoando o Código int Alias. Taken(int indx) ; ref = indx; mov r 4,

Aperfeiçoando o Código int Alias. Taken(int indx) ; ref = indx; mov r 4, r 0 ; Trans. Index(&ref); { add r 0, sp, #0 inf ref = indx; str r 4, [sp] Trans. Index(&ref); bl Trans. Index indx += 5; indx += Displace. Index(indx); ; indx += 5; add r 4, #5 indx += Dither. Index(indx); ; indx += Displace. Index(indx); return indx; mov r 0, r 4 bl Displace. Index ; 00000028 add r 4, r 0 } Observe que a variável indx é mantida agora em r 4, sem exigir repetidos STR/LDR para [sp, #0] ; indx += Dither. Index(indx); mov r 0, r 4 bl Dither. Index ; 00000034 add r 0, r 4

Módulo VI Laboratório

Módulo VI Laboratório