|
Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.
Mensajes - colitroni
Páginas: [1]
1
« en: Domingo 19 de Octubre de 2003, 08:51 »
Bueno, creo q el tema es saber como tratar este tipo de operaciones, ya q si por ejemplo divides por 9 o por cualquier otro no multiplo ya tienes el problema que expongo, estoy convencido q se pueden realizar estas operaciones pero no tengo idea de como tratarlas.
Salu2.
2
« en: Jueves 16 de Octubre de 2003, 21:51 »
Suponiendo instrucciones del 8086:
Los registros son de 16 bits y entonces trabajar con enteros (2 bytes) no hay problema ya que si haces una operacion por ejemplo:
mov ax,0FFFFh mov bx,10 mul bx
El resultado ahora lo pone en DX:AX con lo que puedes acceder al numero completo sin problema alguno
Ahora digamos que quiero dividir 40.002.850 (Long int) entre diez, yo intento hacer algo así, por ejemplo:
mov dx,0262h ; parte alta del numero mov ax,06522h ; parte baja del numero mov bx,10 div bx y aqui el programa termina con un error, ya que en la division el cociente iria a AX y el resto a DX, pero es que DX sigue teniendo la parte alta de ese entero largo (porque el resultado es entero largo tb) ..... y en fin mi problema es que no sé como se puede trabajar con numeros long int (4 bytes) teniendo registros de 16 bits para operaciones de suma, resta multiplicacion y división... a ver si alguien me hace ver la luz. Lo que tengo claro es que la variable numero seria DWord que son 4 bytes..... AYUDA.
Salu2.
3
« en: Jueves 16 de Octubre de 2003, 21:30 »
Pues eso digo, quiero aprender ensamblador..... y en ello estamos Nivel: Principiante
4
« en: Jueves 16 de Octubre de 2003, 21:25 »
Yo me baje este libro en pdf hace poco, la verdad es q me he bajado: Assembly lenguage step by step (Ensamblador paso a paso) The Art of Assembly Language Lo puedes bajar en pdf con los ejemplos y librerias en esta direccion, aparte que hay + cosas interesantes: http://webster.cs.ucr.edu/ metete en Dos Assembly y veras esto y +. Salu2.
5
« en: Miércoles 15 de Octubre de 2003, 14:32 »
El usuario puede teclear un nº entre 0 y 65535 que es lo que corresponde a 2 bytes unsigned, ya que en el print_num no tengo encuenta el signo. La entrada termina cuando el usuario termina con enter. El nº queda almacenado en num y el procedimiento quedaria como sigue:
intronum proc near push ax push bx push dx lea bx,num ; bx apunta a num xor dx,dx ; pongo a cero dx mov [bx],dx introcar: mov ah,01h int 21h ; espero caracter de usuario -> viene en al cmp al,13 ; si es enter.... jz fin ; terminamos sub al,48 ; convierto el caracter a digito mov dl,al ; guardo el digito en dx mov ax,[bx] ; cargo en ax el valor momentaneo de la variable push dx ; al multiplicar por word afecto a dx por eso lo guardo mul diez ; lo multiplico por 10 ojo el resultado es dx:ax pop dx ; recupero el valor de dx add ax,dx ; le sumo el digito introducido para obtener el valor momentaneo mov [bx],ax ; guardo el numero en la variable num jmp introcar: ; voy a por el siguiente digito fin: pop dx pop bx pop ax ret intronum endp
Ahora quiero tratar con nº mayores de 2 bytes (ya q estos caben en 1 reg y es facil la transferecia mem-reg-mem) Mi siguiente reto es intentar nº de 4 bytes con lo que ya podria almacenar nº bastante grandes. Mira a ver que te parecen las siguientes ideas:
1) Creo variable tipo dd (DoubleWord) p.e.: numero dd ? 2) Con LES ax,numero creo q tendria el word bajo en AX y el alto en ES, con lo que pasando ES a DX ya tendria mi nº en DX:AX dispuesto para realizar cualquier operacion aritmetica, esto correcto??? 3) Tengo 1 duda q quiero preguntarte, una vez modificado ese nº DX:AX como lo paso otra vez a la variable numero, hay alguna instruccion de carga directa que me pudiera servir??? o podria hacerlo son SI apuntando a num y meter AX y luego incrementar SI en 2 y meter DX ???
Por cierto, en tu codigo al dividir, el resto no estaria en DX y el digito en al????
Espero tus respuestas, Salu2.
6
« en: Jueves 9 de Octubre de 2003, 02:48 »
Asi a bote pronto, tb se me ocurre hacerlo con una operacion and, ya que si el bit menos significativo está a 1 el nº seguro q es impar, corregirme si me equivoco
He realizado lo que comento arriba y el programa quedaria asi:
DSEG SEGMENT 'DATA' num dw 2456 ;numero que se introduce msgp db 'El numero introducido es par.$' msgi db 'El numero introducido es impar.$' DSEG ENDS
SSEG SEGMENT STACK 'STACK' DW 100h DUP(?) SSEG ENDS
CSEG SEGMENT 'CODE' START PROC FAR ;todo esto para terminar el programa con ret PUSH DS MOV AX, 0 PUSH AX ; empieza programa MOV AX, DSEG MOV DS, AX mov bx,num ;pongo en bx el numero introducido and bx,1 ; compruebo el bit 0 cmp bx,1 ; si bx=1 es impar je impar mov dx,offset msgp ; preparo el mensaje par jmp continua impar: mov dx,offset msgi ; preparo el mensaje impar continua: mov ah,09h ; muestro el mensaje en pantalla int 21h RET START ENDP
;*******************************************
CSEG ENDS
END START ; set entry point.
El programa funciona perfectamente. Salu2.
7
« en: Jueves 9 de Octubre de 2003, 02:43 »
Bueno, pues he encontrado el pequeño fallo. Era que como divido por word, no tenia en cuenta que dx no es cero llegado a esa linea, ya que en dl pongo el valor ascii del caracter para sacarlo por pantalla, asi pues me salia un nº enorme y claro al dividir por 10 me daba error de desbordamiento por división, la solucion la he encontrado leyendo en esta peich, por si os sirve de ayuda a los q como yo estamos empezando: http://www.sinergia-web.com.mx/clases/a ... lase12.htmAsi pues, funciona correctamente poniendo la ultima parte como queda: mov ax,cx ; cargo el divisor en ax xor dx,dx ; pongo a cero el word alto ya que el cociente es dx:ax div diez ; y le quito 1 cero push ax ; lo guardo en la pila cmp ax,1 jae SacaCifra Como veis he insertado un xor dx,dx para ponerlo a cero. Tambien hay que poner un pop ax justo antes del ret, o poner ret 2 para que desapile el ultimo push ax cuando ya no hay cifras que sacar. Salu2.
8
« en: Jueves 9 de Octubre de 2003, 00:21 »
Bueno, esta es mi primera incursion en este lenguaje despues de leer y ver ejemplos. Lo que hago en el programa es leer un nº por teclado 2 bytes y lo que quiero es imprimirlo por pantalla y aqui es donde tengo el problema:
La tecnica que sigo es hallar el divisor (1,10,100,1000,10000) dependiendo de las cifras que tiene el nº introducido por el usuario; luego voy dividiendo el nº por el divisor, despues divido el divisor (para quitarle ceros) y ahi se produce un error de DIVIDE ERROR, el proc es el siguiente:
las definiciones que realizo son:
a dw ? ;contiene el nº introducido
diez dw 10 ;cte de valor 10
PRINTNUM PROC NEAR mov dl,10 ; introduzco 1 retorno de carro mov ah,02 int 21h mov dl,13 ; introduzco 1 retorno de carro mov ah,02 int 21h mov ax,1 ; contador para saber el nº de cifras q tiene a mov bx,a ; cargo en bx la variable a bucle: mul diez cmp ax,bx jbe bucle ; multiplico ax por 10 hasta que ax>bx ojo el resultado es dx:ax div diez ; asi tiene ax las mismas cifras q bx en este punto push ax ; guardo el divisor SacaCifra: pop cx ; meto el divisor en cx mov ax,bx ; cargo en ax la variable cuyos digitos quiero mostrar div cx ; y la divido por cx q será 1,10,100,1000 o 10000 mov bx,dx ; guardo el resto q es lo q queda por sacar mov dx,ax ; ya que en ax está el cociente add dl,30h ; así tengo el caracter ascii q coresponde al digito mov ah,02 ; lo saco en pantalla int 21h mov ax,cx ; cargo el divisor en ax div diez ; y le quito 1 cero ------------ ERROR QUE ME DA: DIVIDE ERROR ------------ push ax ; lo guardo en la pila cmp ax,1 jae SacaCifra ret PRINTNUM ENDP
Por cierto, al que quiera aprender como yo estoy haciendo, le recomiendo el emu8086 que es emulador, ensamblador y desensamblador todo en 1, funciona en Win9x,ME y XP y lo bueno es q si haces burradas, no se cuelga ya q es un emulador;) Si quisierais el nº de serie os podria pasar el mio para registrarlo;)
Salu2 y Espero vuestras respuestas
Páginas: [1]
|
|
|