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