Assembly, o básico

Assembly é um linguagem da programação, estritamente relacionada com a arquitetura do computador, nesse artigo falarei sobre arquitetura CISC da intel em 16 e 32 bits, a maioria dos programas escritor para a arquitetura intel devem funcionar em AMDs.

A grande vantagem dessa linguagem de programação esta no controle que ela oferece sobre a máquina, a velocidade e o tamanho final do programa. Porem mesmo com todas essas vantagem ela é de forma alguma recomendada para ser usada em projetos grandes por causa do número grande de variavés ( muito mais além do espaço de memoria alocado) que tem que se manter controle, o que torna o desnvolvimento estremamente lerdo e penoso, porem eu acho extremamente interessante compreender o funcionamento de algo baixo nivel o que traz uma base sobre o que realmente acontece nos programas.

O primeiro fato a ser mencionado é a diferença entre as notação disponibilizadas, vou chama-las de notação da intel e notação da AT&T, mas qual seria essa diferença? bem as mnemônicas são basicamente identicas – podendo ter alguma variação dependendo do compilador – mas a grande diferença esta em como é determiado a origem e o destino dos dados, a arquitetura da intel segue esse padrão “mnemonico destino origem” já a notação da AT&T faz o oposto “mnemonico origem destino”, como base desse artigo vou usar o nasm – network assembler – que usa a notação da intel.

O segundo fato a ser mencionado são o registradores da cpu, eles são pequenos espaços de memória usados para fazer as operações matemáticas, para um processador 32 bits da intel nós temos os registradores mais importantes: eax(extended accumulator), ebx(extended base), ecx(exetended counter), edx(extended data), ebp(extende base pointer), esp(extented source pointer) esi(source index, edi(destination index)) para 16 bits temos, ah al(accumulator high/low), bh bl, ch cl, dh dl,  além dos registradores de 8 bits e nos processadores modernos 64 bits.

Tem que se ter em mente que os registradores compartilham o espaço, ou seja, a parte ‘baixa’ do eax, é na verdade ah e al, de tal foram que se você modificar ah ou al eax também vai ser alterado:

[----------------[---ah---|---al---]]eax

Isso é verdade para os registradores ‘a’, ‘b’, ‘c’ e ‘d’, lembre-se que os registradores de 8 bits também estão dentro dos de 16 bit e os de 32 bit estão dentro dos de 64 bits.

Terceiro fato, a estrutura de um arquivo de código em assembly:

label: mnemonico [valor1(destino)] [valor2(orgiem)] ;comentário

nenhuma parte é obrigatoria, de forma que você pode ter apenas uma label na linha, ou um mnemonico com seus argumentos, ou um comentário, ou todos juntos. Importante notar que nem sempre vão ser dois argumentos para o mnemonico, podendo ter 0, 1, 2 ou mais em instruções mais especificas.

Quarto fato, mnemonicos são nomes dados a instruções do processador, e em muitos casos são fáceis de se compreender, como `MOV eax, ecx` que move o conteúdo de ecx para eax na notação da intel `ADD` `SUB` `MUL` são outros exemplos, outro fato sobre os mnemonicos é que eles não são case-senstive, então `MOV` e `mov` são equivalentes, a lista dos mnemonicos é extensa, para uma listagem completa

Add comment 12 Junho 2009

Considerações sobre fritar um ovo em uma sanduicheira

Em momento de fome e preguiça a gente recore a métodos não ortodoxos, eu resolvi fritar um ovo em uma sanduicheira para não sujar louça e aqui ficam algumas observações:

Ligue a sanduicheira antes de colocar o ovo

Não use oleo

Use o lado de “fora” – concavo não convexo – da colher para passar margarina

A gema precisa ou de mais sal ou de mais margarina

Add comment 12 Junho 2009

malloc, uma nova abordagem

Faz algum tempo desde meu primeiro post sobre a função malloc, ele não esta muito bem estruturado ficando rasoavelmente inconpreensivel então aqui uma nova abordagem no tópico:

A função malloc é uma função da bilbioteca padrão da linguagem C, a sua função é alocar dinamicamente espaços de memória para poder ser usado no programa, mas qual a utilidade disso?

Bem, vamos supor que nós tenhamos que escrever um programa que trabalha com matrizes, então nos criamos uma array bidimensional para armazenar os valores da matrizes para fazer os calculos, simples não é? mas pera ai, e se o tamanho da matriz variar? hora o usuario pode digitar uma matrz 2×2, hora 3×3, ate mesmo algo como 255×255, ai nós temos um problema, talvez se nós criarmos uma matriz grande de forma que o usuario não seja capaz de enche-la, digamos algo em torno de 1000×1000, dai nós usamos uma variavel para contar o número de linhas e outra para o número de colunas da matriz, perfeito! sera?

Bem, a abordagem acima funciona, mas sinceramente ela é horrivel, se for algum programa para auxiliar estudantes do ensino médio matrizes não passam de 4×4, são 8 elementos de um total de 1.000.000, um disperdicio tremendo de memória! Por outro lado se for uma aplicação cientifica nada garante que o total de dados não seja maior do 1.000.000, e o pior se nós temos que trabalhar com um número variavel de matrizes, como a gente faria? criar 1000 matrizes para ter certeza que não ficamos sem? uma abordagem horrivel, mas o que malloc tem a ver com tudo isso?

malloc permite que a gente crie durante a execução do programa uma matriz do tamanho que quisermos, mas como!? Simples, se pergunta para o usuario o tamanho da matriz que ele quer, então cria-se a matriz do tamanho que o usuario disse:

n = tamanho_matriz(); // pseudo-funcao que pergunta o tamanho da array para o usuario
int **ptr, i;
ptr = malloc(sizeof(int*)*n);
for( i=0; i<n; i++){
ptr[i] = malloc(sizeof(int) * n);
}

Mágico isso não é? mas como funciona? bem malloc leva como argumento o total de bytes para alocar, por isso do sizeof() que retorna o tamanho de um tipo de dado em bytes, e retorna um ponteiro para o inicio dessa seção de memória, o ponteiro é do tipo void*, e a razão disso é bem simples, malloc aloca espaço para qualquer tipo de dados, inclusive struct (desde que você use `sizeof(struct struct_name)`) então o tipo de retorna não poderia ser um ponteiro para algum tipo senão sem tipo( isso mesmo void quer dizer sem tipo) por isso você deve ter se deparado com coisas assim:

ptr = (int*)malloc(sizeof(int)*n);

onde o `(int*)` é um casting, a lógica esta certa afinal se o seu ptr for do tipo int* nada errado com esse casting de um void* para int* – inclusive no meu post anterior eu uso isso – mas de fato ele é redundante porque a conversão é implicita, fica a seu cretério usa-lo ou não.

Agora um ponto importante sobre o malloc, porque o compilador não tem como saber qual é a quantia de memória a ser alocada – ela só é definida durante execução pelo usuario – ele não pode libera-la, por isso não se esqueça de usar a função free(), você só precisa passar o ponteiro que o malloc lhe deu para a função free() que ela se encarrega do resto:

free(ptr);

só mais uma coisa, não se esqueça do `#include <stdlib.h>` para poder usar a função ;D

Add comment 12 Junho 2009

Customizando PS1 – zsh

O texto exibido pelo shell antes do comando a ser executado, é na realidade uma variavel ambiente, no caso PS1, assim se você digitar no shell:

export PS1="$"

Você terá o seu prompt igual a “$”, mas isso não é nada interessante, muito menos útil, por isso o shell permite o uso de expressões especiais tanto para dar estilização ( negrito itálico etc.) como para mostrar informações úteis como  o diretório atual o nome do host usuario hora etc., exemplo:

export PS1="%m %T:"

No exemplo a cima o “%m” e o “%T” irão mostrar o nome da máquina local e a hora respectivamente,repare que é um sinal de porcentagem % seguido de uma letra que depois é expandido ( em outras palavras substituido) para um determinado valor, aqui tem uma lista ( para o zsh) de valores a serem usados na variavel do prompt:

%l – atual tty
%M – nome completo da do host (máquina atual)
%m – primeira parte do nome do host ( meu.host no caso seria exibido meu)
%n – nome do úsuario
%# – identificação de úsuario (# para root e % para usuarios)
%d – mostra o diretorio atual – como em um ‘pwd’ -
%-nd – n especifica um número máximo de subdiretorios ha serem exibidos
%~ – mesmo que %d mas nesse caso o diretório home é substituido por ~
%D – data no formato ano-mês-dia
%T – horas no formato de 24h
%t – horas em am/pm
%* – horas no formato de 24h + os segundo
%W – data no formato mês-dia-ano

Nota: como o % é usado para marcar uma expansão, se você quiser usa-lo no texto do seu prompt você tem de “escapa-lo”, exemplo:

export PS1="%%"

o seu prompt seria apenas %.

E para expansão de estilo:

%B – coloca negrito da fonte
%U – coloca sublinhado da fonte
%S – coloca italico da fonte
%F{cor} – adiciona cor, as cores são:
black, red, green, yellow, blue, magenta, cyan, white
%K{cor} – adicionar cor de fundo

nota: você precisa determinar onde termina a aplicação do estilo, no caso é o carater de escape “%” seguido da letra da opção que aplica o estilo. Exemplo:

export PS1="%F{cyan}%n%f:"

Teria como resultado “usuario:” onde usuario é o seu nome de usuario em azul claro seguido de dois pontos sem cor ( porque a mudança de cor foi encerrada antes deles com o %f) . Você não é abrigado a encerar o efeito visual, assim se você quiser que o nome do comando sendo digitado seja visto em negrito, no exemplo acima seria só adicionar o %B depois dos dois pontos:

export PS1="%F{cyan}%n%f:%B"

A lista completa dos valores possiveis para o prompt esta no final da página de uma das páginas do manual do zsh `man 1 zshmisc` para ve-la.

Além da variavel PS1 existe a PS[2-4] e RPS[12], onde PS2 em frente é usado para demonstrar subniveis, no caso se você digitar echo ” <enter> vai aparecer a sua PS2, e a RPS1 é equivalente a PS1 porem é mostrada do lado direito da tela, como exemplo minha configuração:

export PS1="%F{cyan}%n%f %1. %(?.%#.%F{red}%#%f) "
export PS2="> "
export RPS1="%F{yellow}%T%f"

Add comment 30 Maio 2009

Acontecimento bizarro da semana

Bem, esse que vos escreve, hoje, estava junto com alguns amigos, se assim devo chama-los depois do ocorrido, e dois dos meus amigos começaram a puxar a cueca de um terceiro, o resultado vocês ja podem ter imaginado, eu ri da cara dos tres, os dois riram da cara do da cueca, e o da cueca gritava porque as bo… bem você pegou a ideia, o problema foi o acontecimento no decorrer, nós resolvemos assistir um dvd de um seriado, bem eu, o da cueca, e um dos dois sentamos no mesmo sofá, eles como tem duvidas sobre a própria sexualidade fizeram fiasco entre dividir o cobertor, eu preferi ficar sem dividir, e como eu não dividi, não tinha cobertor para mim, mas isso não vem ao caso, durante o mini fiasco pela divisão do cobertor o da cueca diz:

“Por que eu sempre tenho que ficar no lado gay” – ele estava sentado no meio, eu estava em uma ponta e o um dos dois estava na outra ponta do sofá, então que vem a resposta do um dos dois – “Porque você já esta acostumado” – depois disso o um dos dois coloca os pés sobre as pernas do da cueca então ele diz – “Hey! tira o seu pé dai, você já me machucou nessa área” – Bem, eu demorei um bom instante para parar de rir, e eles continuaram discutindo a relação até que cada um parou e simplesmente cruzou os braços assistindo televisão, e, dividindo o cobertor …

Add comment 18 Janeiro 2008

Alerta aos leitores

Se vocês lerem os textos ate o final E se eu não esquecer nenhuma palavra, vocês irão entender os textos. =D

Eu poderia ter nomeado esse post como frase da semana, mas como eu não acho que eu vá criar uma frase irónica toda semana ficou assim mesmo.

Add comment 18 Janeiro 2008

Free(), passagem por referência e a minha função

Continuando o artigo Entendendo ponteiros e a função malloc.

O uso de ponteiros permite modificar o valor de outras variáveis, então o que acontece se nós usarmos ponteiros ao invés de variáveis como parâmetros de uma função? O valor da variável que teve o seu endereço passado como parâmetro poderá ser modificado na função, afinal se uma variável em main teve o seu endereço passado como parâmetro para a função que atribui esse valor em um ponteiro será criado uma referência entre o ponteiro e a variável e quando for modificado o valor para o qual o ponteiro aponta o valor da variável também será modificado.

Para se fazer isso você deve lembrar que o uso do simbolo “&” fornece o endereço da variável na memoria para usar nos ponteiros e que para se declarar um ponteiro nós colocamos um “*” na frente do nome do ponteiro, lembrando disso é possível criar funções com passagem por referência.

Então você deve declarar a função dessa maneira:

exemplo(int *ponteiro);

Assim você vai estar criando um ponteiro para inteiros, não uma variável, e quando você for usar a função em main você deve usar assim:

int i;
exemplo(&i);

Afinal de contas, o valor de um ponteiro deve ser o endereço na memoria de um variável, e dentro da função você deve mudar o valor da variável para a qual o ponteiro aponta usando o “*” na frente do nome do ponteiro, isso é passagem por referencia, simples assim.

Aqui fica o exemplo da minha função primos, não é a melhor implementação, mas é funcional:

int primos(int num,int *vetor){

int i, aux, candidato, num_primos, loop, *ptr;

// definir os dois primeiros numeros primos
*vetor=2;
*(vetor+1)=3;

// definindo numero de primos conhecidos
num_primos=2;

// candidato comeca do proximo numero primo(5)
// candidato de 2 em 2 para evitar numeros pares
for(candidato=5;candidato<=num;candidato+=2){

  loop = 1;

// i=1 porque nao ha pares
  for(i=1;loop;i++){

// testando se o candidato e multiplo de algum numero
    if(candidato % *(vetor+i) == 0){

// sem verdadeiro, sair do loop pois nao e primo
      loop = 0;
    }
    aux = *(vetor+i);

// se o quadrado do numero primo for maior
// que o candidato esse sera primo
    if(aux*aux > candidato){

      loop = 0;
      *(vetor+num_primos)=candidato;
      num_primos++;
      }
    }
  }
return num_primos;
}

Um ponto importante sobre a memória alocada através da função malloc é que ela é persistente, isso significa que há duas maneiras de libera-la para uso novamente, dizendo para a memoria ser liberada ou fechando o programa e isso trás uma importante implicação, se você continuar usando a memória do computador e não liberta-la o resultado provavelmente vai ser um vazamento de memória, aqui entra a função free:

void free(void *pointer);

Desse jeito:

int *p;
p = (int *)malloc(sizeof(int)*5);
if(p == NULL){
exit(EXIT_FAILURE);
}
free(p);

Tudo o que nós precisamos fazer é passar o ponteiro desnecessário para a função free() que vai dizer ao sistema operacional que o espaço armazenado pela função malloc() pode ser reutilizado.

Agora duas notas, 1. A função free() não destrói o ponteiro, você poderá usa-lo novamente. 2. A função diz ao sistema operacional que aquele espaço da memória está livre, e que ele pode designa-lo a outro programa, e até isso não acontecer os dados não serão modificados e você não terá restrição de acesso a esse espaço da memória, mas mesmo assim, não use o vetor depois de passar o ponteiro pela função free() porque inevitavelmente alguma hora o espaço vai ser reutilizado.

1 comment 13 Janeiro 2008

é engraçado mas é assustador

Como de costume, final de semana = tempo livre, tempo livre = college humor, quando eu leio o primeiro texto “Cara conhece guria que ele estava perseguindo pelo facebook”, wtf!

Para quem não sabe o facebook seria a versão americana do orkut.

Sinceramente, eu sou geek, desocupado nos finais de semana, mas o pessoal que passa a tarde mandando scrap tem sérios problemas mentais … nada contra …

Add comment 13 Janeiro 2008

conseqüências da teoria do caos

De acordo com a teoria do caos o voar de um borboleta pode causar um tornado.

A teoria usa como base idéia de que pequenos acontecimentos podem gerar outros acontecimentos em cadeia cada vez maiores, explicando a frase a cima, mas e qual seria a conseqüência disso?

essa daqui

Add comment 12 Janeiro 2008

Ressuscite pixeis mortos!

Nesse site eles trazem uma tecnica que eu nunca tinha visto antes na minha vida!

é inacreditável, serio mesmo

Add comment 12 Janeiro 2008

Previous Posts


 

Janeiro 2010
S T Q Q S S D
« Jun    
 123
45678910
11121314151617
18192021222324
25262728293031

Principais mensagens

Tópicos recentes

Feeds