Duda con punteros

Programando el Amstrad en Ensamblador.
Reglas del Foro
Debido a que hay varios temas pidiendo ayuda para programar en ensamblador máquinas distintas al Amstrad CPC, con micro distinto al Z80 y que incluso dependen del sistema operativo, nos vemos en la necesidad de poner por escrito que estos posts son bienvenidos pero que no es el lugar adecuado ya que por estos lares nos dedicamos más al ensamblador del Z80, un microprocesador de 8 bits que tuvo su gran auge en ordenadores y consolas de los años 80.

De todas formas, esto no quita que alguien que sepa del asunto pueda postear alguna respuesta pero es más fácil encontrar foros dedicados a programar en ensamblador en Windows o MS-DOS que ayudarán más que nosotros:
http://www.lawebdelprogramador.com/news ... nsamblador
ronsonmaria
Lechoncillo
Lechoncillo
Mensajes: 4
Registrado: Lun 30 Sep , 2013 9:42 pm

Duda con punteros

Mensajepor ronsonmaria » Mié 01 May , 2019 8:14 pm

Buenas noches:

Tengo una duda. Tengo esto:

Código: Seleccionar todo

_level1::
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4
Me gustaría saber un par de cosas en ensamblador:

a) ¿ Cómo puedo crearme un puntero llamado auxiliar que apunte al mismo sitio que _level1 ?

b) ¿ Cómo haría para desplazar auxiliar x bytes a la derecha ?

Gracias

Avatar de Usuario
llopis
Forum Addict
Forum Addict
Mensajes: 362
Registrado: Dom 17 Jun , 2018 10:22 pm
Ubicación: Asturias
Contactar:

Re: Duda con punteros

Mensajepor llopis » Mié 01 May , 2019 8:30 pm

_level1 es la dirección de memoria que quieres. O sea que si la quieres usar con un "puntero", simplemente la cargas:

Código: Seleccionar todo

ld hl, _level1
Para mover ese "puntero" a la derecha, simplemente lo incrementas la cantidad que quieras:

Código: Seleccionar todo

inc hl
¿Era eso lo que preguntabas?

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8420
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Duda con punteros

Mensajepor Artaburu » Mié 01 May , 2019 8:45 pm

Yo suelo usar algo así:

Código: Seleccionar todo

;init pointer

ld hl, _level1
ld (auxiliar),hl

;recorriendo datos
ld hl, (auxiliar)
ld a, (hl)
inc hl
ld (auxiliar),hl

;o si sabes que te quieres desplazad 10 bytes, por ejemplo:
ld bc,10
add hl,bc
;y en hl ya tienes el puntero apuntando donde quieres.


auxiliar:
.dw _level1

_level1::
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
.db 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Salu2,
Arta

Avatar de Usuario
Artaburu
Trasteador
Trasteador
Mensajes: 8420
Registrado: Vie 07 Oct , 2005 6:18 pm
Ubicación: En tu pantalla

Re: Duda con punteros

Mensajepor Artaburu » Mié 01 May , 2019 9:00 pm

también puedes usar los registros ix e iy si los desplazamientos son siempre conocidos, por ejemplo porque lo que tengas es una estructura de datos

Código: Seleccionar todo

ld ix, _level1
ld a, (ix+10)
ld a, (ix+45)
...
Salu2,
Arta

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: Duda con punteros

Mensajepor ronaldo » Jue 02 May , 2019 10:04 am

Aparte de lo que ya te han comentado @artaburu y @llopis, es importante tener en cuenta que _level1:: no es un puntero, es una etiqueta. Las etiquetas son un nombre que se le pone a una dirección de memoria. Básicamente son más como una constante. Aunque sean parecidos, no es lo mismo que un puntero. Un puntero, por definición es una variable que contiene una dirección de memoria. La única opción que cumple esta definición es la que ha propuesto @artaburu:

Código: Seleccionar todo

auxiliar::
.dw _level1

_level1::
....
Aquí se crea espacio para 2 bytes en memoria que almacenan la dirección de _level1 inicialmente, y que se pueden modificar escribiendo sobre ellos. Así, esos 2 bytes almacenarían tu puntero, y usas la etiqueta auxiliar:: para acceder a ellos. Aquí puedes ver que la etiqueta auxiliar te sirve para acceder a tu puntero (que son los 2 bytes, no la etiqueta), y puedes ver que la etiqueta como tal no es un puntero. En este caso, la etiqueta se parece más a la variable, aunque sigue siendo sólo la dirección fija de memoria donde está almacenado el puntero.

Por extensión, también llamamos puntero al uso de direcciones de memoria en registros. Por eso también te dicen de cargar _level1 en HL o IX y utilizar los registros para acceder a la memoria. Necesitas cargarlo en un registro para poder modificarlo, porque _level1 sólo es una constante fija. Aunque esto no cumpliría estrictamente la definición, todos lo manejamos como puntero y lo llamamos así, porque es casi lo mismo, con la única diferencia de que no se almacena permanentemente en memoria.

Imagino que necesitas la versión de almacenarlo en memoria, porque lo que querrás es mantener una dirección que vayas luego actualizando. La puedes crear como te ha comentado @artaburu y luego la modificas cargándola en un registro, haciendo los cálculos que necesites, y volviendo a escribirla en la posición auxiliar:: de memoria.

Código: Seleccionar todo

ld hl, (auxiliar) ;; cargar los 2 bytes que hay en la posición 'auxiliar::' de memoria en HL
;;; Aquí haces las cuentas que quieras
ld (auxiliar), hl ;; Volver a escribir en memoria en la posición 'auxiliar::' para actualizar el valor del puntero

ronsonmaria
Lechoncillo
Lechoncillo
Mensajes: 4
Registrado: Lun 30 Sep , 2013 9:42 pm

Re: Duda con punteros

Mensajepor ronsonmaria » Dom 05 May , 2019 9:02 pm

Buenas tardes:

Muchas gracias. Ya me funciona. Una única observación:

No podría usar (ix) por tener más de 128 Bytes no?

Saludos

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: Duda con punteros

Mensajepor ronaldo » Dom 05 May , 2019 9:51 pm

No podría usar (ix) por tener más de 128 Bytes no?
Puedes usar IX perfectamente, el problema lo tienes en que el desplazamiento que añades a IX no puedes hacerlo variable, es decir:

Código: Seleccionar todo

ld ix, _level1 ;; IX toma la dirección donde empieza _level1
ld a, (ix + 10) ;; Legal, 10 es una constante
ld a, (ix + b) ;; Ilegal, b es un registro, sólo se pueden usar constantes
Eso quiere decir que para acceder a toda tu tabla no podrías hacerlo con un bucle, sino que deberías hacerlo así:

Código: Seleccionar todo

ld a, (ix + 0)
ld a, (ix + 1)
ld a, (ix + 2)
;;.......
O bien, incrementando IX en un bucle, que es lo mismo que haces con HL

Código: Seleccionar todo

loop:
ld a, (ix)
;;...
inc ix
jr loop
Por supuesto, si lo hicieras en la primera opción, la tabla debería ocupar como máximo 256 bytes (podrías apuntar al punto medio de la tabla en vez de al inicio, e ir desde -128 a +127). La primera opción la puedes usar con un bucle si usas código automodificable. El desplazamiento (-127 a +128) es el 3er byte de la instrucción ld a, (ix + #). En código máquina esto sería:

Código: Seleccionar todo

loop:
;; Asumimos que loop es la dirección 0x4000 de memoria
;; ENSAMBLADOR - CODIGO MAQUINA
ld a, (ix + 0) ;;..0x4000: DD 7E [00]
;; calculos
ld hl, loop + 2 ;;.0x4020: 21 02 40
inc (hl) ;;........0x4023: 34
jp loop ;;.........0x4024: C3 00 40
He marcado con [] el byte que contiene el desplazamiento (el 0 que sumamos a IX). Uso HL para apuntar a donde ese byte está guardado en memoria (posición 0x4002, o lo que es lo mismo, loop+2) e incremento el contenido de esa posición. Así puede usar lo que inicialmente sería una constante como si fuera una variable, modificando el opcode en cada paso. OJO: Eso sólo se puede hacer en RAM: en ROM no se pued modificar la memoria. Por tanto, esto no funcionaría en un cartucho tipo dandanator o similar.


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro


La Comunidad Española
ESP Soft, juegos para tu CPC Foro de Amstrad CPC Todos los juegos para CPC en un CD Web dedicada al Amstrad CPC (utilidades) Información útil para el CPC (talleres) Selección de juegos de Amstrad CPC Mundo CPC Pree Play then any Key CPC Basic