Mudança

Fala povo :)
Seguinte, decidi reavivar a idéia do blog e dessa vez me esforçar pra levar mais a sério. Para assumir tal compromisso comigo mesmo até registrei um domínio onde coloquei o blog. Ele pode ser acessado por http://www.gilgalab.com.br
Os novos posts serão todos feitos lá.

Grande abraço!

Anúncios

Dica: Source Code Highlighter

Fala pessoal!

Quando estava escrevendo os posts aqui para o blog, precisava de uma ferramenta que me ajudasse a colorir o código e me fornecesse o html para ele colorido. Depois de experimentar várias ferramentas por aí, a mais bacana que encontrei e com suporte ao maior número de linguagens foi o Quick Highliter.

quickhighlighter.jpg

Você digita o código na linguagem desejada, seleciona no drop down a linguagem que está utilizando, define as opções que deseja e seu código sai colorido! Outra coisa bacana é que ele também faz indentação.
Para aqueles que gostam de um código fácil de ler e bem organizado, tá ai uma ótima dica.

Java: Conectando-se ao MySQL

Olá pessoas,

Aqui estou de novo tentando voltar a postar hehehe. Hoje vou mostrar um exemplo simples de classe em Java para se conectar ao MySQL, para que mais pra frente eu possa mostrar algumas coisas bacanas para se fazer com JSP + TagLibs + MySQL + Servlets :) (Não sou grande fã de usar frameworks quando ainda não conheço bem a linguagem).
Bom, chega de lenga lenga, e vamos ao que interessa :D

Para poder brincar você vai precisar do MyConnector/J instalado. Ele pode ser obtido em: http://dev.mysql.com/downloads/connector/j/5.1.html!
Ao baixar o Connector/J você encontrará dentro do .zip (ou do .tar.gz) um arquivo com o nome parecido com: mysql-connector-java-5.1.5-bin.jar. Certifique-se que você adicionará esse arquivo ao seu CLASSPATH pois ele será necessário para que os exemplos que usaremos funcionem.

Agora vamos criar um banco de dados simples para utilizarmos nos nossos exemplos:

CREATE DATABASE projeto;
USE projeto;
CREATE TABLE usuario (
   id_usuario INT NOT NULL PRIMARY KEY AUTO_INCREMENT
   ,nome VARCHAR(100)
   ,idade INT(3)
);

E aqui inserimos alguns dados, para podermos consulta-los.

INSERT INTO usuario (
   nome
   ,idade
) VALUES (
   "Henrique"
   ,22
);

INSERT INTO usuario (
   nome
   ,idade
) VALUES (
   "José"
   ,35
);

INSERT INTO usuario (
   nome
   ,idade
) VALUES (
   "Andreia"
   ,21
);

Vou começar com uma classe bem simples, que simplesmente se conecta ao MySQL, e ao longo do texto vamos incrementa-la para que faça mais coisas. Vamos então a primeira classe:

package com.heap.db;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;

public class MySQL {

    private String host;
    private String user;
    private String pass;
    private String database;
   
    public Connection c;
   
    /**
     * Construtor da classe
     *
     * @param host Host em que se deseja conectar
     * @param database Nome do database em que se deseja conectar
     * @param user Nome do usuário
     * @param pass Senha do usuário
     */

    public MySQL( String host, String database, String user, String pass ) {
        this.pass = pass;
        this.user = user;
        this.host = host;
        this.database = database;
    }
   
    /**
     * Método que estabelece a conexão com o banco de dados
     *
     * @return True se conseguir conectar, falso em caso contrário.
     */

    public boolean connect() {
        boolean isConnected = false;
        String url;
       
        url = "jdbc:mysql://"+this.host+"/"
              +this.database+"?"
              +"user="+this.user
              +"&password="+this.pass;
             
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            System.out.println(url);
            this.c = DriverManager.getConnection(url);
            isConnected = true;
        } catch( SQLException e ) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            isConnected = false;
        } catch ( ClassNotFoundException e ) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            isConnected = false;
        } catch ( InstantiationException e ) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            isConnected = false;
        } catch ( IllegalAccessException e ) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            isConnected = false;
        }
       
        return isConnected;
    }
}
 

Código bastante simples como podemos perceber. A primeira linha indica que essa classe pertence ao pacote com.heap.db. É importante ressaltar isso, porque teremos de importar esse código para dentro da nossa classe que será o nosso programa de verdade, que chamará o método de conexão. Perceba também que no código eu não faço nenhum tratamento especial para as exceptions, apenos imprimo o erro. Essa não é uma técnica muito bacana, pois podemos perder informações. Eu gost de criar uma outra classe que faça o handle das exceptions e salve os erros em algum lugar, para que eu possa consulta-los se ncessário, mas em nosso caso aqui é o bastante apenas imprimi-las.

import com.heap.db.MySQL;

public class TesteDB {

    public static void main (String [] args) {
        MySQL db = new MySQL("localhost","projeto","root","12345");
        if ( db.connect() ) {
          System.out.println("Conectado!");
        };
      }
   
}
 

Logo na primeira linha desse código é feito o import da classe que se conecta ao MySQL. No método main() criamos uma instancia da classe MySQL com os parametros para especificar onde estamos conectando, e logo na sequência chamamos o método para conectar.
Agora é hora de testar isso tudo. Então apenas para motivos de esclarecimento, vamos dar uma olhada em como ficou a estrutura do nosso diretório.

C:\Projeto
¦   TesteDB.class
¦   TesteDB.java
¦
+—com
¦   +—heap
¦      +—db
¦               MySQL.class
¦               MySQL.java
¦
+—lib
         mysql-connector-java-5.1.5-bin.jar

No meu caso já se pode ver os arquivos .class pois já compilei o código, mas aqui vai a forma como iremos compilar:

À partir da raiz do projeto (No meu caso aqui C:\Projeto (Sim, estou usando windows porque estou escrevendo isso do computador do trabalho :|))
javac -cp . com\heap\db\MySQL.java
javac -cp . TesteDB.java

Agora que tudo está compilado, basta rodar!

java TesteDB
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
         at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
         at java.security.AccessController.doPrivileged(Native Method)
         at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
         at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
         at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
         at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
         at java.lang.Class.forName0(Native Method)
         at java.lang.Class.forName(Class.java:169)
         at com.heap.db.MySQL.connect(MySQL.java:32)
         at TesteDB.main(TesteDB.java:7)
com.mysql.jdbc.Driver

Oops! Algo saiu errado. Lembram-se no começo quando eu disse que precisavamos do Mysql Connector/J e que ele estivesse no CLASSPATH? Bem, como da pra notar na estrutura de diretórios, eu coloquei o Connector/J no diretório lib porém não fiz referência a essa lib quando fui rodar o programa, o que causou o erro. Então vamos rodar o comando correto e ver o que acontece:

java -cp .;lib\mysql-connector-java-5.1.5-bin.jar TesteDB
jdbc:mysql://localhost/projeto?user=root&password=12345
Conectado!

Como pode perceber, agora parece que tudo funcionou! A opção -cp do comando java diz ao interpretador qual o CLASSPATH a utilizar. Nesse caso mandei que utilizasse o diretório atual, e o arquivo .jar do Connector/J.

Muito legal isso tudo, porém uma classe que simplesmente conecta no banco é bastante inútil. Vamos então melhorar a nossa classe MySQL, adicionando algums métodos para que possamos consultar dados.

O primeiro método que irei adicionar é um que recebe uma query como parametro e retorna um ResultSet. O ResultSet nada mais é do que um resource que representa a tabela. Eis o código:

/**
     * Esse método executa a query dada, e retorna um ResultSet
     * Talvez fosse melhor idéia fazer esse método lançar uma exception
     * a faze-lo retornar null como eu fiz, porém isso é apenas um exemplo
     * para demonstrar a funcionalidade do comando execute
     *
     * @param query String contendo a query que se deseja executar
     * @return ResultSet em caso de estar tudo Ok, null em caso de erro.
     */

    public ResultSet executar( String query ) {
        Statement st;
        ResultSet rs;
       
        try {
            st = this.c.createStatement();
            rs = st.executeQuery(query);
            return rs;
        } catch ( SQLException e ) {
            e.printStackTrace();
        }
       
        return null;
    }

Nesse trecho de código, criamos um Statement a partir da nossa conexão. O objeto Statement nos permite executar comando no nosso banco de dados.
E para testar esse código, nós iremos rodar uma query contra o nosso banco de dados que criamos no começo desse texto. O nosso código da classe TesteDB vai ficar dessa maneira:

import java.sql.ResultSet;
import java.sql.SQLException;

import com.heap.db.MySQL;

public class TesteDB {

    public static void main (String [] args) {
        MySQL db = new MySQL("localhost","projeto","root","12345");
        String query;
       
        if ( db.connect() ) {
            System.out.println("Conectado!");
            System.out.println("Rodando uma query contra o banco");
         
            query = "select * from usuario";
            ResultSet rs = db.executar(query);
            try {
                if ( rs != null ) { // Verifica se a query retornou algo
                    while ( rs.next() ) {
                        // Podemos referenciar a coluna pelo índice
                        System.out.println("Id: " + rs.getInt(1));
                       
                        // Ou pelo seu nome
                        System.out.println("Nome: " + rs.getString("nome"));
                        System.out.println("Idade: " + rs.getInt("idade"));
                        System.out.println("—————————-");
                    }
                }
          } catch ( SQLException e ) {
              e.printStackTrace();
          }
         
        };
      }
   
}
 

Recompile e rode esse código da mesma forma que fizemos lá em cima, você deve ter uma saída como essa:

jdbc:mysql://localhost/projeto?user=root&password=12345
Conectado!
Rodando uma query contra o banco
Id: 1
Nome: Henrique
Idade: 22
—————————-
Id: 2
Nome: Jos‚
Idade: 35
—————————-
Id: 3
Nome: Andreia
Idade: 21
—————————-

No código você pode reparar que eu referenciei as colunas tanto utilizando um índice (cada coluna tem um índice numérico que vai de 1, representando a primeira coluna da tabela, até N onde N é o número de colunas na tabela). Repare também que para cada tipo de dados que a tabela possui utilizamos um método get distinto. Para a lista de métodos get que se pode utilizar, consulte a documentação do ResultSet .
Já melhoramso bastante! Agora nossa classe já tem uma função, ela consulta dados na nossa base! Vamos ver então como podemos ecrever um método para inserir dados em nossa tabela. De volta na classe MySQL adicione o seguinte método:

/**
     * Executa uma query como update, delete ou insert.
     * Retorna o número de registros afetados quando falamos de um update ou delete
     * ou retorna 1 quando o insert é bem sucedido. Em outros casos retorna -1
     *
     * @param query A query que se deseja executar
     * @return 0 para um insert bem sucedido. -1 para erro
     */

    public int inserir( String query ) {
        Statement st;
        int result = -1;
       
        try {
            st = this.c.createStatement();
            result = st.executeUpdate(query);
        } catch ( SQLException e ) {
            e.printStackTrace();
        }
       
        return result;
    }

Esse método poderá ser utilizado tanto para inserir dados, como para apagar ou atualizar. Novamente criamos um Statement e chamamos um método para executar a nossa query. Para maiores informações sobre os métodos da classe Statement consulte a documentação.

Vejamos então como ficou a nossa classe MySQL completa, e um programa de exemplo que a utiliza.

MySQL.java

package com.heap.db;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;

public class MySQL {

    private String host;
    private String user;
    private String pass;
    private String database;
   
    public Connection c;
   
    /**
     * Construtor da classe
     *
     * @param host Host em que se deseja conectar
     * @param database Nome do database em que se deseja conectar
     * @param user Nome do usuário
     * @param pass Senha do usuário
     */

    public MySQL( String host, String database, String user, String pass ) {
        this.pass = pass;
        this.user = user;
        this.host = host;
        this.database = database;
    }
   
    /**
     * Método que estabelece a conexão com o banco de dados
     *
     * @return True se conseguir conectar, falso em caso contrário.
     */

    public boolean connect() {
        boolean isConnected = false;
        String url;
       
        url = "jdbc:mysql://"+this.host+"/"
              +this.database+"?"
              +"user="+this.user
              +"&password="+this.pass;
             
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            System.out.println(url);
            this.c = DriverManager.getConnection(url);
            isConnected = true;
        } catch( SQLException e ) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            isConnected = false;
        } catch ( ClassNotFoundException e ) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            isConnected = false;
        } catch ( InstantiationException e ) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            isConnected = false;
        } catch ( IllegalAccessException e ) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            isConnected = false;
        }
       
        return isConnected;
    }
   
    /**
     * Esse método executa a query dada, e retorna um ResultSet
     * Talvez fosse melhor idéia fazer esse método lançar uma exception
     * a faze-lo retornar null como eu fiz, porém isso é apenas um exemplo
     * para demonstrar a funcionalidade do comando execute
     *
     * @param query String contendo a query que se deseja executar
     * @return ResultSet em caso de estar tudo Ok, null em caso de erro.
     */

    public ResultSet executar( String query ) {
        Statement st;
        ResultSet rs;
       
        try {
            st = this.c.createStatement();
            rs = st.executeQuery(query);
            return rs;
        } catch ( SQLException e ) {
            e.printStackTrace();
        }
       
        return null;
    }
   
    /**
     * Executa uma query como update, delete ou insert.
     * Retorna o número de registros afetados quando falamos de um update ou delete
     * ou retorna 1 quando o insert é bem sucedido. Em outros casos retorna -1
     *
     * @param query A query que se deseja executar
     * @return 0 para um insert bem sucedido. -1 para erro
     */

    public int inserir( String query ) {
        Statement st;
        int result = -1;
       
        try {
            st = this.c.createStatement();
            result = st.executeUpdate(query);
        } catch ( SQLException e ) {
            e.printStackTrace();
        }
       
        return result;
    }
}
 

TesteDB.java

import java.sql.ResultSet;
import java.sql.SQLException;

import com.heap.db.MySQL;

public class TesteDB {

    public static void main (String [] args) {
        MySQL db = new MySQL("localhost","projeto","root","12345");
        String query;
        int result;
       
        if ( db.connect() ) {
            System.out.println("Conectado!");
            System.out.println("Rodando uma query contra o banco");
         
            query = "select * from usuario";
            ResultSet rs = db.executar(query);
            try {
                if ( rs != null ) { // Verifica se a query retornou algo
                    while ( rs.next() ) {
                        // Podemos referenciar a coluna pelo índice
                        System.out.println("Id: " + rs.getInt(1));
                       
                        // Ou pelo seu nome
                        System.out.println("Nome: " + rs.getString("nome"));
                        System.out.println("Idade: " + rs.getInt("idade"));
                        System.out.println("—————————-");
                    }
                }
          } catch ( SQLException e ) {
              e.printStackTrace();
          }
         
          System.out.println("Inserindo dados na tabela");
          query = "insert into usuario (nome, idade) values (‘Maria’,23)";
          result = db.inserir(query);
          if (  result > -1 ) {
              System.out.println("Dado inserido com sucesso! Resutlt = " + result);
          } else {
              System.out.println("Erro inserindo dado.");
          }
         
          query = "update usuario set idade = 99";
          result = db.inserir(query);
          if (  result > -1 ) {
              System.out.println("Dado inserido com sucesso! Resutlt = " + result);
          } else {
              System.out.println("Erro inserindo dado.");
          }
         
        };
      }
   
}
 

O procedimento para compilar e rodar é o mesmo que seguimos lá no começo.
Bom, por hoje é só pessoas! Espero que esse pequeno tutorial possa ajudar aqueles que como eu estão começando! Continuem estudando e boa sorte!
No próximo vamos falar de coisas pouco mais avançadas e ainda mais divertidas.

Para maiores informações consulte os links:
MySQL AB: Basic JDBC Concepts
Java Documentation
Google

PL/SQL Oracle: Identificando o último dia da semana no mês

Fala pessoal!

Fiquei sumido desde o primeiro post. A vida está uma correria, e mal tenho tido tempo de fazer qualquer coisa :|
Bom, estava no trabalho dia desses e precisava de uma lógica para identificar qual é o último dia do mês que caia durante a semana. Depois de pesquisar um pouco como poderia fazer isso, e pensar por alguns instante, cheguei ao seguinte código.

  1. DECLARE
  2.    v_ultimo_dia VARCHAR2(10);
  3.  
  4. BEGIN
  5.  
  6.    v_ultimo_dia := TO_CHAR(LAST_DAY(SYSDATE),‘D’);
  7.    IF v_ultimo_dia = 7 THEN  — Sabado
  8.       v_ultimo_dia := TO_CHAR((LAST_DAY(SYSDATE)1),‘DD/MM/YYYY’);
  9.    ELSIF v_ultimo_dia = 1 THEN — Domingo
  10.       v_ultimo_dia := TO_CHAR((LAST_DAY(SYSDATE)2),‘DD/MM/YYYY’);
  11.    ELSE
  12.       v_ultimo_dia := TO_CHAR((LAST_DAY(SYSDATE)),‘DD/MM/YYYY’);
  13.    END IF;
  14. END;

A variável “v_ultimo_dia” agora contém a data no formato DD/MM/YYYY do último dia do mês atual.
E essa foi uma dica rápida para hoje.
De agora em diante, quando o tempo para postar for curto, pretendo tentar postar dicas rápidas, e eventualmente postar textos mais detalhados sobre coisas mais específicas.
Espero que todos aproveitem.

Até o próximo ;)

Bootstrap Simples

0. Introdução

Esse fim de semana andei estudando um pouco de assembly. Decidi fazer um bootstrap para ver se me animava um pouco, e acabou me voltando a vontade de realmente brincar de criar o meu sistema operacional. Como tudo precisa de um começo, decidi que o bootstrap seria um belo lugar para começar.
Vejamos então como é que fazemos para dar um boot na maquina e o que é que a(o) BIOS (Basic Input Output System) espera para iniciar o sistema operacional.
Quando o computador inicia e o POST termina, a BIOS faz uma chamada para ler o primeiro setor do disco que está definido como primário no setup. Funciona assim:

a) Olha o primeiro setor do disco definido no setup
b) Encontrou setor de boot válido?
c) Sim. Lê o setor e carrega o código para o segmento 7C00h na memória.
d) Não. Parte para o próximo dispositivo da lista de boot e vai para a) até encontrar.
e) Caso não encontre em nenhum dos dispositivos, exibe mensagem de erro padrão da BIOS.

A Lista de software que usei:
1. NASM – Para compilar o código
2. QEMU – Maquina virtual que uso para testar o setor de boot
3. dd – Utilizado para escrever os dados no disco

1. O setor de boot

Quando definimos o disco no qual desejamos dar o boot, a BIOS chama uma interrupção (19h se nao me engano), para ler o primeiro setor desse disco. O primeiro setor é o que se encontra na posição CHS (Cylinder Head Sector) 0:0:1. Cada setor no disco tem 512 bytes, então como a BIOS lê o primeiro setor do disco, nosso ‘programa’ precisa ter 512 bytes ou menos. Meu objetivo aqui não é de falar muito sobre HCS, maiores informações você pode encontrar aqui.
O que identifica se temos um setor de boot válido ou não?
O setor de boot tem uma ‘assinatura’, os últimos dois bytes do setor devem ser ‘0xAA55’. Quando essa assinatura é encontrada, os 512 bytes são carregados para a memória na posição 7C00h e o programa é executado.

2. O código

Como já diria o conde Drácula em ‘Castlevania: Symphony of the Night’: “Enough talk!”.
Vamos dar uma olhada então em um código bem simples, que imprime uma string na tela.

; Boot.asm

ORG 7C00h                   ; Posição onde estaremos quando o código for

                            ; carregado para a memória

mymsg: db 'Olá Setor de BOOT',10,0

xor ax,ax                   ; Limpando ax

mov si,mymsg                ; Nossa mensagem em SI

putstr:
        lodsb               ; Coloca o byte apontado em SI em AL, e incrementa
                            ; o contador

        or al,al            ; Verificamos se encontramos o byte '0' da string
        jz hang;            ; Se sim, paramos de imprimir
        mov ah,0x0E         ; Função para escrever

        mov bx,0x0007       ; Define a página e a cor onde escrevemos
        int 0x10            ; Interrupção de video
        jmp putstr          ; Imprimir proximo caracter

hang:
        jmp hang            ; Após impressão, entramos em loop infinito

times 512-($-$$)-2 DB 0     ; Preenchemos o resto da memória com '0's

                            ; até 510 bytes
DW 0xAA55                   ; Assinatura do setor de boot

Acredito que o código esteja auto explicativo. Você deve precisar manjar um pouco de assembly, então se não entendeu o código, procure estudar um pouquinho de assembly.
Vamos agora compilar o nosso código, criar um disco para o QEMU, e escrever o nosso setor de boot no disco.

$ nasm boot.asm -f bin -o boot.bin
$ qemu-img create /tmp/boot.img -f qcow 1M
$ dd if=boot.bin of=/tmp/boot.img

Com isso feito, basta agora executar o QEMU e dizer que desejamos usar o arquivo /tmp/boot.img como nosso disco.

$ qemu /tmp/boot.img -m 16

O resultado é a nossa frase impressa logo após a BIOS fazer o POST.

3. Colocando código no Disco

Bom, agora que já sabemos dar o boot, está na hora de colocarmos código no disco e executar esse código. Esse é um processo um pouco mais complicado, mas vamos que vamos!
A idéia agora é fazer com que o nosso programa de boot chame um binario que esteja gravado no disco e o execute. Então precisaremos escrever dois programas distintos: Um para ser o nosso setor de boot, e um que será chamado por ele. “Show me the code”

; Boot2.asm

ORG 7C00h

mov si,msg

prntMsg:                    ; Imprime a mensagem em SI
  lodsb
  mov ah,0x0E

  mov bx,0x0007
  int 10h
  or al,al

  jnz prntMsg

mov [drv],dl                ; DL contém o identificador da unidade em que 
                            ; o setor de boot foi encontrado

; Inicializar o disco. Aqui colocamos a cabeça do disco no inicio dele

.diskSetup
  mov ax,0        ; Função para resetar o disco rígido
  mov dl,[drv]    ; O drive que vamos resetar

  int 13h         ; Chama a interrupção de disco
  jc .diskSetup   ; Se der erro, tentamos de novo

; Após resetar o disco, colocaremos a cabeça no setor que o programa se 

; encontra e carregamos o programa na memória

.diskRead
  mov ah,02h    ; Função para ler o disco
  mov al,3      ; Ler 3 setores (512 * 3 bytes)

  mov ch,0      ; Apontar para o cilindro 0
  mov cl,0x02   ; Ler a partir do setor 2 (2, 3 e 4)

  mov dh,0      ; Cabeça 0
  mov dl,[drv]  ; Disco de onde queremos ler os dados

; Os dados que lemos com essa função são armazenados em ES:BX
; No nosso caso aqui entao teremos 1000h:0

  mov bx,0x1000
  mov es,bx

  mov bx,0

  int 13h       ; Interrupção do disco
  jc .diskRead  ; Em caso de erro, tenta de novo

jmp 1000h:0;    ; Aqui nós pulamos para o nosso código que acaba de ser
                ; carregado na memória

hang:
  jmp hang      ; Loop infinito

drv db 0
msg db 'Chamando programa do HD',13,10,0

times 512-($-$$)-2 db 0   ; Completa o espaço do setor que sobra com 0s

DW 0xAA55                 ; Assinatura do setor de boot nos ultimos dois bytes

Esse código então, como da para perceber, lê o código do disco, coloca o código na posição de memória 1000h:0 e pula para lá para começar a execução. Bom, precisamos agora então do programa que desejamos ler do disco e executar. Esse programa, assim como o primeiro exemplo vai simplesmente imprimir uma mensagem na tela.

;  Programa.asm

mov ax, 1000h ; Atualizar os registros de segmentos

mov ds, ax
mov es, ax
mov si, msg ; Mensagem em SI

putstr:
lodsb
or al,al
jz hang

mov ah,0x0E
mov bx,0x0007
int 0x10

jmp putstr

hang:
jmp hang

msg db 'Bla bla bla!',13,10,0

Nesse programa nós atualizamos os registros de segmento para o mesmo endereço onde carregamos o programa do nosso HD, e executamos a rotina basica de imprimir a mensagem na tela, e entrar em loop infinito.
Para executar esse exemplo, os paso são parecidos. Vejamos:

$ nasm boot2.asm -f bin -o boot2.bin
$ nasm programa.asm -f bin -o programa.bin
$ qemu-img create ./boot2.img -f qcow 1M
$ dd if=boot2.bin of=./boot2.img
$ dd if=programa.bin of=./boot2.img bs=512 seek=1
$ qemu ./boot.img -m 16

O comando ‘$ dd if=programa.bin of=./boot2.img bs=512 seek=1’ coloca o nosso código no segundo setor do disco, pois conforme definimos em nosso código, é la que nosso bootstrap está esperando encontra-lo.

4. Conclusão
Bom pessoal, é isso ai. Como o tpitulo disse, é um bootstrap simples, apenas para dar um gostinho de como funciona, e trazer mais animo para maiores pesquisas.
Espero que tenham gostado e que possa ser útil para alguém.

Até o próxmo :D

Introdução

O objetivo aqui é bastante simples. Demonstrar códigos diversos, demonstrar seu funcionamento e procurar trazer de forma simples e prática o conhecimento. Não pretendo colocar apenas código em uma única linguagem específica, ou sobre um tópico específico; irei escrever sobre aquilo que estiver pesquisando no momento, ou que venha a ser de meu interesse.

Sinta-se a vontade para mandar sugestões ou comentários!

Regards,