Gente, estou estudando assembly na faculdade, e eu pedi uns exercicios extras para o meu professor, consegui fazer todos , menos um. Ele disse que vai me ajudar semana que vem, mas nao quero esperar, enfim, estou vendo uns videos de assembly no youtube, mas ainda nao entendi a lógica da pergunta.
Será que alguém pode me dar umas dicas ?
Eu sei que tem que usar CMP arg1,arg2 , mas o CMP gera qual resposta ? 0 se for igual e 1 se for diferente ???
Aqui esta a pergunta :
““
Sabendo que nas posições de memória 270 a 3C0 temos armazenados valores hexadecimais correspondentes a caracteres alpha, elaborar um programa para aarmazenar a partir do endereco 400, as letras minúsculas e a partir do endereco 560 as letras maiúsculas.(Lembrar que na tabela ascII temos A = 41h, e a=61h);
””
Bom, eu sei que tenho que fazer um loop; Não tenho certeza se precisa de JMP.
Preciso de dicas pra solucionar, será alguem pode , por favor , me ajudar?
aaa, estou usando Debug no CMD do XP na maq. Virtual.
==
Tomara que voces possam me ajudar.
Enquanto isso vou tentando alguma coisa aqui, e vou postando os resultados ;
CMP não altera nenhum registrador, exceto o registrador de flags.
O que ele faz é a mesma coisa que uma subtração (SUB __, __) mas em vez de jogar o resultado em um registrador, joga o resultado fora e só alera as flags.
Por exemplo:
CMP AX, BX
JE label
faz o seguinte: subtrai AX de BX e joga o resultado fora. Se o resultado for zero, o flag Z (Zero) será setado. Então a instrução JE será executada porque o flag Z está setado.
Na verdade, a intenção é algo equivalente a:
if (AX == BX)
goto label;
Para fazer um loop contado (mais ou menos um “for decrescente”, com o índice diminuindo em vez de aumentando), o mais adequado é usar a instrução LOOP mesmo.
Por exemplo, digamos que você queira fazer uma coisa que em C seria:
int cx = 10;
int ax = 0;
label:
ax = ax + 1;
cx--;
if (cx != 0) goto label;
O equivalente disso em Assembly é:
MOV CX, 10
XOR AX, AX ; é um truque para limpar AX e usar um byte a menos
label:
INC AX
LOOP label ; LOOP decrementa um do registrador CX e se CX não for zero, volta para o label indicado
Para fazer o equivalente de um FOR, você deve se lembrar que ele é um WHILE disfarçado. Ou seja,
for (int cx = 0; cx < 10; cx++) {
bx--;
}
equivale a
int cx = 0;
while (cx < 10) {
bx--;
cx++;
}
que por sua vez equivale a:
int cx = 0;
label1:
if (! (cx < 10)) goto label2;
bx--;
cx++;
goto label1;
que por sua vez é:
XOR CX, CX
label1:
CMP CX, 10
JGE label2
DEC BX
INC CX
JMP label1
label2:
Note que ! (x < y) é a mesma coisa que x >= y (estou, obviamente, simplificando as coisas. Se eu estivesse comparando dois números de ponto flutuante eu não afirmaria isso. Além disso, a comparação GE que fiz aqui é correta se estivermos falando de inteiros com sinal. Se for inteiros sem sinal, eu deveria usar JBE, não JGE. )
Para mais detalhes, veja em:
http://en.wikibooks.org/wiki/X86_Assembly/Control_Flow
Normalmente você constrói loops da seguinte maneira:
for (int bx = 10; bx <= 25; bx++) {
dx += 7;
}
equivale a
int bx = 10;
int cx = 15;
do {
dx += 7;
cx--;
} while (cx > 0);
que em Assembly é:
MOV BX, 10
MOV CX, 15
label1:
ADD DX, 7
LOOP label1
Desculpe a demora pra responder. Fiquei pensando como resolver esse problema,mas estou com dificuldade .
Eu sei , pela tabela ASCII, quando que é letra maiúscula e quando é letra minúscula, mas ainda não sei como fazer essa Comparação… talvez incrementando um registrador, mas o problema é comparar esse registrador com o que… Pq na memória são 16 bits né ?
Vou pensar em alguma coisa…
Para saber se algo é uma letra maiúscula, basta ver se ela está entre ‘A’ e ‘Z’, e para minúsculas, entre ‘a’ e ‘z’. Um exemplo:
if ('a' <= AL && AL <= 'z') {
BX = BX + 2;
}
equivale a:
CMP AL, 61H
JB notlowercase
CMP AL, 7AH
JA notlowercase
SUB BX, 2
notlowercase:
...
Uma dica: escreva (e se puder teste) o seu programa com uma linguagem de nível um pouco maior (como C). Uma vez feito isso, reescreva o programa em Assembly. Garanto que fica bem mais fácil (e pode até criar uma otimização, se for o caso, porque você consegue enxergar mais oportunidades de escrever a mesma coisa de forma mais eficiente).
Sabendo que nas posições de memória 270 a 3C0 temos armazenados valores hexadecimais correspondentes a caracteres alpha, elaborar um programa para armazenar a partir do endereco 400, as letras minúsculas e a partir do endereco 560 as letras maiúsculas.(Lembrar que na tabela ascII temos A = 41h, e a=61h);
[code]
int counter;
int destinyLow = 400;
int destinyHigh = 560;
low = 3c0 - 270;
for(int i = 0; i <low ; i++)
{
if (low[i] == lowercase)
{
destinyLow = low[i];
destinyLow++;
}else
if(low[i] == CapsLock ) //Esqueci o nome, é highCase?
{
destinyHigh = low[i];
destinyHigh++;
}
}[/code]
Meu deus, como vou passar isso pra assembly?
Vou tentar aqui:
//O que eu não soube fazer em assembly, eu deixei em linguagem O.O
Me da mais uma ajuda? rsrsrs
int cx;
int SI = 400;
int BP = 560;
dh = 41h
dl = 61h;
cx = 3c0 - 270;
//Agora não sei fazer a parte de baixo... deixa eu tentar usar CMP
V1 label : CMP dh,cx
Jump if cmp == true to next line
SI[] = cx
mov si,si+1
if cmp == false, LOOP V1
cx = 3c0 - 270;
V2 label : CMP dl,cx
Jump if cmp == true to next line
BP[] = cx
mov bp,bp+1
if cmp == false,loop V2
}
Gente, esse meu código as vezes funciona, as vezes não…
Elaborar um programa para escrever a partir do endereco 300,as letras maiusculas existentes nas posições de memoria 200 a
2FF, e escrever, a partir do endereço 400,as letras minusculas existentes entre 200 a 2FF
[code]
a 1000
mov cx,100 //Valor do Loop
mov ax,0000 // aux
mov dh,5A // maiusculas
mov dl,7A // minusculas
mov si,300 // A partir de 300 escrever as maiusculas
mov bp,400 // as minusculas
mov DI,200
v1º
cmp dh,[DI]
JNC 1040 // dh > [DI] .: logo é letra minuscula
mov ax,[DI]
mov [bp],AX // Guardei em 400+
INC BP
V1a
INC DI
loop v1
int 3
a 1040
mov ax,[DI]
mov [si],ax
INC SI
jmp V1a[/code]