[?] Inicializar vector y trabajar con el

Iniciado por MeCraniDOS, 3 Julio 2014, 17:55 PM

0 Miembros y 2 Visitantes están viendo este tema.

MeCraniDOS

Hola  ;D

Estoy intentando calcular la media de unos numeros para practicar un poco, pero tengo algunos fallos de concepto, he trabajado antes con ARM, pero las instrucciones en ASM son un poco diferente..

el codigo es este

Código (asm) [Seleccionar]
include 'FASM\INCLUDE\WIN32AX.INC'

.data
vector rd 8 ; Reservamos 8 bytes

.code
start:
mov eax, 0 ;Media
mov ecx, 0 ;Contador

;Inicializamos el vector
mov [vector], 7
mov [vector+1], 8
mov [vector+2], 5
mov [vector+3], 2
mov [vector+4], 9
mov [vector+5], 1
mov [vector+6], 0
mov [vector+7], 3

for:
add eax, [vector] ;Aqui esta el error
inc ecx
cmp ecx, 8
jne for

       ; Aqui divido para obtener la media

invoke ExitProcess, 0

.end start


Se que para los que sepan, es algo muy basico... hay alguna manera de inicializar el vector de una manera mas sencilla? y otra cosa, para ir sumando el valor del vector en un bucle com seria? Intentaba simular esto

Código (cpp) [Seleccionar]
for(int i=0;i<8;i++)
{
   eax += vector[i];
}


No quiero codigos completos, solo una ayudita con las instrucciones  :rolleyes:

Saludos
"La física es el sistema operativo del Universo"
     -- Steven R Garman

Eternal Idol

#1
No se si entendi muy bien:
Código (asm) [Seleccionar]
vector db 1, 2, 3, 4, 5
...
movzx edx, byte [vector+ecx]
add eax, edx

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

MeCraniDOS

#2
Cita de: Eternal Idol en  3 Julio 2014, 18:49 PM
No se si entendi muy bien:

Le he hecho en C para que se entienda mejor


   int eax=0, ecx=0;
   int Vector[] = {7,8,5,2,9,1,0,3};

   for(ecx=0;ecx<8;ecx++)
   {
        eax += Vector[ecx];
   }

   eax /= ecx;


Entonces lo que quería saber era si se podía inicializar como lo he hecho en C

Código (asm) [Seleccionar]
;Inicializamos el vector
mov [vector], 7
mov [vector+1], 8
mov [vector+2], 5
mov [vector+3], 2
mov [vector+4], 9
mov [vector+5], 1
mov [vector+6], 0
mov [vector+7], 3


Eso equivale a esto en C

   int Vector[8];

   Vector[0] = 7;
   Vector[1] = 8;
   Vector[2] = 5;
   Vector[3] = 2;
   Vector[4] = 9;
   Vector[5] = 1;
   Vector[6] = 0;
   Vector[7] = 3;


Y hacerlo asi en un  :o




Al final el código me ha quedado así con las modificaciones que me has dicho Eternal

Código (asm) [Seleccionar]
include 'FASM\INCLUDE\WIN32AX.INC'

.data
       vector db 7, 8, 5, 2 ,9 ,1 ,0, 3

.code
       start:
               mov eax, 0      ;Media
               mov ecx, 0      ;Contador

               for_add:
                       movzx edx, byte [vector+ecx]
                       add eax, edx
                       inc ecx
                       cmp ecx, 8
                       jne for_add

               mov ecx, 0 ;Reiniciamos ecx

               for_div:
                       sub eax, 8
                       cmp eax, 8
                       inc ecx
                       jae for_div

               invoke ExitProcess, 0

.end start


Por cierto, dos cosas, la rutina for_div se puede simplificar? Es que en arm lo tenia que hacer asi porque no hay operacion de division, pero en asm he visto que si, pero solo pones el registro a dividir, no entre que valor lo quieres dividir  :huh: :huh:

Y la otra, que diferencia hay entre esto?


Código (asm) [Seleccionar]
vector db 7, 8, 5, 2 ,9 ,1 ,0, 3
Código (asm) [Seleccionar]
vector rb 8

Pensaba que db era para una unica variable, y rb (reserved byte) para vectores, ya que especificas cuanto espacio quieres reservar  :rolleyes:
"La física es el sistema operativo del Universo"
     -- Steven R Garman

Eternal Idol

Cita de: MeCraniDOS en  4 Julio 2014, 00:20 AM

Le he hecho en C para que se entienda mejor


   int eax=0, ecx=0;
   int Vector[] = {7,8,5,2,9,1,0,3};

   for(ecx=0;ecx<8;ecx++)
   {
        eax += Vector[ecx];
   }

   eax /= ecx;


Entonces lo que quería saber era si se podía inicializar como lo he hecho en C

Evidentemente entonces lo habia entendido bien.

Cita de: MeCraniDOS en  4 Julio 2014, 00:20 AMPor cierto, dos cosas, la rutina for_div se puede simplificar? Es que en arm lo tenia que hacer asi porque no hay operacion de division, pero en asm he visto que si, pero solo pones el registro a dividir, no entre que valor lo quieres dividir  :huh: :huh:

Código (asm) [Seleccionar]
mov ECX, 25 ;dividimos por 25
cdq ;limpiamos EDX
idiv ECX ;EDX:EAX es dividido por ECX
;EAX=COCIENTE EDX=RESTO


Cita de: MeCraniDOS en  4 Julio 2014, 00:20 AM
Y la otra, que diferencia hay entre esto?

Código (asm) [Seleccionar]
vector db 7, 8, 5, 2 ,9 ,1 ,0, 3
Código (asm) [Seleccionar]
vector rb 8

Pensaba que db era para una unica variable, y rb (reserved byte) para vectores, ya que especificas cuanto espacio quieres reservar  :rolleyes:

Notese que estas usando char (byte, db/rb), si queres usar un int usa dword (y el add puede ser directo).

db:
char Vector[] = {7,8,5,2,9,1,0,3};
rb:
char Vector[8];
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

MeCraniDOS

#4
Cita de: Eternal Idol en  4 Julio 2014, 09:02 AM
Notese que estas usando char (byte, db/rb), si queres usar un int usa dword (y el add puede ser directo).

Al utilizar dword ocupo 4 bytes en la memoria, por lo que tendria que incrementar el contador de 4 en 4  :-\

Citar00401000  07 00 00 00 08 00 00 00  ......
00401008  05 00 00 00 02 00 00 00  ......
00401010  09 00 00 00 01 00 00 00  .......
00401018  00 00 00 00 03 00 00 00  .......

Lo de la division lo veo raro  :rolleyes:

Poniendo el codigo como me has dicho, los registros quedan de esta manera una vez realizada la operación:

CitarEAX 00000001
ECX 00000008
EDX 00000007
EBX 7FFDF000
ESP 0007FF90
EBP 0007FF98
ESI 00000000
EDI 00000000
EIP 00402021 2_-_copi.00402021

Código (asm) [Seleccionar]
include 'FASM\INCLUDE\WIN32AX.INC'
   
.data
vector dd 7, 8, 5, 2 ,9 ,1 ,0, 3

.code
start:
mov eax, 0 ;Media
mov ecx, 0 ;Contador
   
for_add:
movzx edx, byte [vector+ecx]
add eax, edx
inc ecx
cmp ecx, 8
jne for_add
   
mov edx, 0 ;Inicializamos edx
idiv ecx ;edx:eax es dividido por ecx
 
;eax = cociente
;edx = resto
   
invoke ExitProcess, 0
   
.end start


No saca muy bien el resultado...  :silbar:

En que estoy metiendo la pata?  :huh:





Código (asm) [Seleccionar]
vector db 7, 8, 5, 2 ,9 ,1 ,0, 3

CitarEAX 00000004
ECX 00000008
EDX 00000003
EBX 7FFDF000
ESP 0007FF8C
EBP 0007FF98
ESI 00000000
EDI 00000000
EIP 00402022 2_-_copi.00402022

Solucionado ;D
"La física es el sistema operativo del Universo"
     -- Steven R Garman

Eternal Idol

#5
No se cual seria el problema al dividir que tenias  ;D

Y si usas DWORD:
Código (asm) [Seleccionar]
add eax, [vector + ecx * 4]
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

MeCraniDOS

#6
Cita de: Eternal Idol en  4 Julio 2014, 14:25 PM
No se cual seria el problema al dividir que tenias  ;D

Y si usas DWORD:
Código (asm) [Seleccionar]
add eax, [vector + ecx * 4]

El problema era que estaba utilizando DWORD, y solo incementaba el contador en 1, por lo que sumaba el valor y luego 3 ceros hasta el siguiente numero, pero se soluciona multiplicando como has hecho  ;D

Otra cosita, utilizando DWORD, no malgastarias memoria? (En este caso, ya que los numeros no son de mas de dos cifras)  :silbar:





En este caso podría utilizar WORD? que ocupa 2 bytes y es numerico

Código (asm) [Seleccionar]
vector dw 7, 8, 5, 2 ,9 ,1 ,0, 3

; ....

add eax, [vector + ecx * 2]
"La física es el sistema operativo del Universo"
     -- Steven R Garman

Eternal Idol

#7
Cita de: MeCraniDOS en  4 Julio 2014, 14:44 PM
El problema era que estaba utilizando DWORD, y solo incementaba el contador en 1, por lo que sumaba el valor y luego 3 ceros hasta el siguiente numero, pero se soluciona multiplicando como has hecho  ;D

Otra cosita, utilizando DWORD, no malgastarias memoria? (En este caso, ya que los numeros no son de mas de dos cifras)  :silbar:

En el codigo de C estabas usando int, que es un DWORD con signo.

Cita de: MeCraniDOS en  4 Julio 2014, 14:44 PMEn este caso podría utilizar WORD? que ocupa 2 bytes y es numerico

Un BYTE puede representar valores entre 0 y 255 asi que en este caso no necesitas un WORD tampoco ... y no, no podes usar add directamente con un WORD, vas a tener que pasarlo a un registro como con BYTE anteriormente; o usar el registro correspondiente en su lugar (al, ax, eax, rax).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

MeCraniDOS

Cita de: Eternal Idol en  4 Julio 2014, 15:38 PM
En el codigo de C estabas usando int, que es un DWORD con signo.

Un BYTE puede representar valores entre 0 y 255 asi que en este caso no necesitas un WORD tampoco ... y no, no podes usar add directamente con un WORD, vas a tener que pasarlo a un registro como con BYTE anteriormente; o usar el registro correspondiente en su lugar (al, ax, eax, rax).

De acuerdo, muchas gracias Eternal  ;D ;D

Saludos
"La física es el sistema operativo del Universo"
     -- Steven R Garman

Eternal Idol

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón