Soluciones Boletin ASM 2004

Anuncio
Problemas
P1.Para facilitar la tarea, suponemos definido en el segmento de datos lo siguiente:
ascii
7_segm
DB
DB
‘0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F’
3fh,06h,…,71h
el núcleo del código sería:
mov dl, al
lea bx, ascii
xlat ascii; equivalente a "mov al, [bx+al]"
mov ch, al
En lugar de una lista, podríamos haber hecho (teniendo en cuenta que los códigos ASCII son
consecutivos para números y letras):
letra:
fin:
mov dl, al
cmp al,9
ja letra
or al,30h; el código ASCII de 0 es 30h
mov ch,al
jmp fin
sub al,10; lo que hay que sumar al código de 'A'
add al,'A'; el ensamblador sustituye 'A' por 41h.
...
ahora 7 segmento:
mov al,dl
lea bx, 7segm
xlat 7_segem
mov cl, al
mov al, dl
P2.Suponemos inicializados a su valor correcto CS y DS
MAX EQU 128; se sustituye en tiempo de compilación
NUM_ELEM
DB 128 ;
SUM
DW ?
MED
DW ?
VALORES DW MAX DUP ?
…
…
inicio:
LEA SI, VALORES
MOV AX, 0
MOV CL, NUM_ELEM
B_SUMA:
ADD AX, [SI]
ADD SI, 2
DEC CL
JNZ B_SUMA
MOV SUM, AX
CWD
MOV BX, NUM_ELEM
IDIV BX
MOV MED, AX
1
En realidad, 128=27. Por tanto, la división podría haberse sustituido por:
MOV CL, 7
SAR DX,1
RCR AX,1
LOOP OTRA
OTRA:
La mayoría de las veces esta secuencia es más rápida aunque suponga la ejecución de más
instrucciones.
P3.El bucle C es:
for (i=99; i>=0; i--)
for (j=99; j>=0; j--)
for (k=99; k>=0; k--)
c[i][j]= a[i][k]+b[i][k];
donde
int i,j,k,a[100][100], c[100][100], c[100][100]
…
mov
word
jmp
@1@58:
;
;
;
mov
jmp
@1@86:
;
;
;
mov
jmp
@1@114:
;
;
;
mov
mov
imul
mov
shl
add
mov
mov
push
mov
mov
imul
mov
shl
add
mov
pop
ptr DGROUP:_i,99
short @1@282
for (j=99;j>=0;j--)
word ptr DGROUP:_j,99
short @1@226
for (k=99;k>=0;k--)
word ptr DGROUP:_k,99
short @1@170
c[i][j]=a[i][k]+b[i][k];
ax,word
dx,200
dx
dx,word
dx,1
ax,dx
bx,ax
ax,word
ax
ax,word
dx,200
dx
dx,word
dx,1
ax,dx
bx,ax
ax
ptr DGROUP:_i
ptr DGROUP:_k
ptr DGROUP:_a[bx]
ptr DGROUP:_i
ptr DGROUP:_k
2
add
push
mov
mov
imul
mov
shl
add
mov
pop
mov
dec
@1@170:
cmp
jge
dec
@1@226:
cmp
jge
dec
@1@282:
cmp
jl
jmp
@@0:
...
ax,word ptr DGROUP:_b[bx]
ax
ax,word ptr DGROUP:_i
dx,200
dx
dx,word ptr DGROUP:_j
dx,1
ax,dx
bx,ax
ax
word ptr DGROUP:_c[bx],ax
word ptr DGROUP:_k
word ptr DGROUP:_k,0
short @1@114
word ptr DGROUP:_j
word ptr DGROUP:_j,0
short @1@86
word ptr DGROUP:_i
word ptr DGROUP:_i,0
@@0
@1@58
P4.-
DI
SI
ceros
pos
neg
otro: mov ax, word
cmp ax, 0
je ceros
jl neg
inc word ptr
jmp fin
ceros:inc word ptr
jmp fin
neg: inc word ptr
fin: add si, 2
loop otro
ptr SI]
[di + 2]
[di]
[di + 4]
3
P6.MOV WORD PTR [DI],0;
MOV CX,8; 8 elementos
OTRO: MOV AL,[SI]
XOR [DI],AL
ADD [DI+1],AL
INC SI
LOOP OTRO
inicializo a la vez paridad [DI] y checksum [DI+1].
P7..MODEL small
.DATA
cadena db 'el helado eel ell'
.STACK
.CODE ; Cadena ASCII, contar las veces de ‘el’
main: mov ax,@data
mov ds,ax
mov si,offset cadena
mov cx,0 ; contador de número de veces de 'el'
otro: mov al,[si]
inc si
cmp al,0 ; código de fin de cadena
je fin
cmp al,'e'
jne otro
cmp byte ptr [si],'l'
jne otro
inc cx
inc si
jmp short otro
fin: mov ah,4ch ; así se termina en MS-DOS
int 21h
END main
P8..MODEL small
.DATA
cont
dw
?
message db 81
db 81 dup (?); la que sea
; suponemos que el primer elemento es la longitud de la cadena
.STACK
.CODE
main:
mov ax, @data
mov ds,ax
mov dx, offset message
inc dx
mov si,dx
mov cl,[si-1]
mov ch,0
mov cont,cx
ordena: mov bl,1; bandera que indica si ha habido cambios
dec cont; se hacen cont-1 comparaciones
jz ordenado
4
mov cx,cont
mov si,dx
; cada pasada se hace con 1 elemento menos (los mayores quedan abajo).
sigue:
mov al,[si]
cmp al,[si+1]
jbe no_cambio
xchg [si+1],al
mov [si],al
xor bl,bl; bl=0 si ha habido cambios
no_cambio:
inc si
loop sigue
cmp bl,0
je ordena ; sólo si bl=1 es que no ha habido cambios (ordenada)
ordenado:
mov
mov
xor
add
si,dx
cl,[si-1]
ch,ch
si,cx
mov ax,4c00h
int 21h
ends
cseg
end main
P9.STRING
SUBSTRING
0
mov bl, 0
mov cx, m
mov ax, SEGMENT
mov ds, ax
mov es, ax
mov di, STRING
continua:
mov si, SUBSTRING
otro:
mov al, [di]
cmp al, 0
je fin
inc di
cmp al, [si]
jne otro
push cx
5
push di
dec di
cld
repe cmpsb
jne distintos
jmp guarda_valores
distintos:
pop di
pop cx
jmp continua
guarda_valores:
mov ax, RESULT
mov ds, ax
mov si, DIRECT
mov [si], SEGMENT
mov [si + 2], DI
fin:
mov ax, RESULT
mov ds, ax
mov si, DIRECT
mov word ptr [si], 0
alternativa:
…
repe cmpsb
jne distintos
mov bl, 1; sí aparece
jmp fin
distintos:
pop di
pop cx
jmp continua
fin:
mov ax, RESULT
mov ds, ax
mov si, DIRECT
cmp bl, 1
je aparece
mov word ptr [si], 0
jmp final
aparece:
mov [si], SEGMENT
mov [si + 2], DI
final:
…
P10..MODEL SMALL
.DATA
cadena db ‘race car0’
temp db 20 dup ?
.STACK
.CODE
main: mov ax, @DATA
mov ds, ax
mov si, cadena
6
mov di, temp
mov bl, 1; en principio es un palíndromo
otro: mov al, [si]
inc si
cmp al, 0
je fin
cmp al, ‘ ‘
je otro
mov [di], al
inc di
jmp otro
fin: mov si, temp
dec di
; compara las cadenas
otro2:
mov al, [si]
cmp al, ‘ ‘
jne sigue
inc si
jmp otro2
sigue:
cmp [di],al
jne no_pal
inc si
dec di
cmp si, di
jb otro2
jmp si_pal
no_pal:
mov bl, 0
si_pal:
mov ah, 4ch
int 21h
end main
P12.; código C de prueba
; #include <stdio.h>
; extern unsigned long fact(unsigned int n);
;
;
;
;
;
main() {
long i;
i=fact(10);
printf("%ld", i);
}
.MODEL small
.CODE
PUBLIC _fact
_fact proc near
push bp
mov bp,sp
mov cx, [bp+4]
7
cmp cx,0
je hecho
dec cx
push cx
call _fact
pop cx
cmp ax,0ffffh
jne sigue
cmp dx,0ffffh
je overfl
sigue:
inc cx
push dx
mul cx
push dx
push ax
mov ax,[bp-2]
mul cx
jc overfl
push ax
mov ax, [bp-6]
mov dx, [bp-4]
add dx,[bp-8]
jnc retorno
overfl:
mov ax,0ffffh
mov dx,0ffffh
jmp short retorno
hecho:
mov dx,0
mov ax,1
retorno:
mov sp,bp
pop bp
ret
_fact endp
end
P13.
; #include <stdio.h>
; extern void mult32(unsigned long k,unsigned long h, unsigned long *r);
; unsigned long k=8,h=2;
; unsigned long r[1]; // define una cadena de 2 long (64 bits) para que
quepa el resultado
; main() {
; mult32(k,h,&r);
; printf("%lx %lx", r[1], r[0]); // en hex., primero parte más
significativa
; }
.MODEL small
.CODE
PUBLIC _mult32
_mult32
proc near
push bp
mov bp,sp
8
mov
mov
mov
mov
cx,word
bx,word
dx,word
ax,word
ptr
ptr
ptr
ptr
[bp+6]
[bp+4]
[bp+10]
[bp+8]
mul bx ; ax*bx=dx:ax
push dx; p1h
push ax; p1l
mov ax,word ptr [bp+10]
mul bx ;dx*bx
push dx;p2h
push ax;p2l
mov ax,word ptr [bp+8]
mul cx ;ax*cx
push dx;p3h
push ax;p3l
mov ax,word ptr [bp+10]
mul cx ;dx*cx
push dx;p4h
push ax;p4l
; sumar los productos parciales,
[bp+10]:[bp+8]
;
*
[bp+6]:[bp+4]
;
---------------;
p1h:p1l
;
p2h:p2l
;
+ p3h:p3l
;
p4h:p4l
mov bx, [bp+12]
mov ax, [bp-4]
mov [bx], ax
mov ax, [bp-2]
add ax, [bp-8]
adc WORD PTR [bp-6],0; suma el carry.
add ax,[bp-12]
; Esto no genera a su vez carry
mov cx,[bp-6]
adc cx,[bp-10]
adc WORD PTR [bp-14],0
add cx, [bp-16]
mov dx,[bp-14]
adc dx,0
mov [bx+2],ax
mov [bx+4],cx
mov [bx+6],dx
mov sp,bp
pop bp
ret
_mult32
endp
end
P14.
; void funcion(long *vector, int longitud);
; Cambiar el signo a los elementos de vector
9
; Se asume longitud > 0
.MODEL small
.CODE
PUBLIC _funcion
_funcion proc
near
push bp
mov bp,sp
mov cx,[bp+6]
mov bx,[bp+4]
otro: not WORD PTR [bx]
;complemento a 2
not WORD PTR [bx+2]
add WORD PTR [bx],1
adc WORD PTR [bx+2],0
add bx,4
dec cx
;|
jne otro;| o bien "loop otro"
fin: pop bp
ret
_funcion endp
end
;Si el modelo fuera large:
.MODEL large
.CODE
PUBLIC _funcion
_funcion proc
far
push bp
mov bp,sp
mov cx,[bp+10]
les bx,[bp+6];es=segmento de vector
;bx=desplaz. de vector
otro: not WORD PTR es:[bx]
not WORD PTR es:[bx+2]
add WORD PTR es:[bx],1
adc WORD PTR es:[bx+2],0
add bx,4
dec cx
;|
jne otro;| o bien "loop otro"
fin: pop bp
ret
_funcion endp
end
;si los números fueran en signo magnitud (como un float, 32 bits)
otro: xor
add
dec
jne
BYTE PTR [bx+3],80h
;cambia sólo el bit más significativo
bx,4
cx
;|
otro;| o bien "loop otro"
10
Descargar