PROGRAMANDO EN ASSEMBLER PARA LA IBM 370

En este "tutorial" voy ir contando la experiencia de no saber nada de assembler hasta ser un programador profesional muy bien pago en assembler para la IBM370.

Esta es una versión del assembler que está basado en la que todavía enseñan en la facultad. Empiezo este tutorial porque no pude encontrar nada de información sobre assembler de IBM 370 en internet.

Lo primero que hay que tener son los archivos para compilarlo: IBM370.zip

Dentro de ese zip hay un archivo llamado ibm360.exe. Ejecútenlo. Les va a instalar el programa en C:\EMU360.

Deszipeen los demás archivos, y guarden los de extensión .mac en los directorios

C:\EMU360\SRC y C:\EMU360\LIB

Copien los archivos de C:\EMU360\BIN a C:\EMU360\SRC

Con esto ya tienen instalados todos los archivos que hay que instalar.

 

Después abrí la ventana del DOS. Inicio / Ejecutar y ahí escribí Command

En el Dos escribí

cd\
cd emu360
cd src
edit hola.mlc

Voy a escribir el primer programa


*0123456789012345678901234567890
HOLA       PPIO 3
           WTO       'Hola mundo!'
           CHAU
           END

El asterisco * es un comentario por lo que no se ejecuta. Los números de arriba son para orientarse.

Los rótulos deben estar al principio.
Las instrucciones de assembler deben empezar abajo del primer 0.
Los demás datos deben estar abajo del otro 0.

Los archivos deben tener siempre la macroinstrucción PPIO con algún registro en este caso 3, CHAU y END.

La instrucción WTO significa Write To y sirve para escribir en pantalla. La palabra a imprimir en pantalla debe estar entre comillas.

Grabo y salgo del edit.

desde el directorio c:\emu360\src\

Escribo

C:\EMU360\SRC>c hola2

y en pantalla aparece esto:


Ya existe el subdirectorio o el archivo TEMP.
..\hola2.mlc
1 archivos copiados.
***********************************************
* PC/370 System Release 4.2 01/07/88 *
* Copyright (C) 1988 Donald S. Higgins *
***********************************************
PC/370 CROSS ASSEMBLER OPTIONS=ACE
STATS SYM=00003 MAXSTD=00001 LIT=00001 MAXLTD=00001 BTMEM=52356
NO ERRORS FOUND
***********************************************
* PC/370 System Release 4.2 01/07/88 *
* Copyright (C) 1988 Donald S. Higgins *
***********************************************
PC/370 LINKAGE EDITOR OPTIONS ON = EFIP
STATS SYM=00001 MAXSTD=00001 BTMEM=57788
NO ERRORS FOUND
"DELTREE" no se reconoce como un comando interno o externo,
programa o archivo por lotes ejecutable.

 

Después de la compilación, voy a estar en el directorio C:\EMU360\SRC\COM

y escribo hola

y aparece en pantalla

Hola mundo!

Listo, tenemos el primer programa compilado.


Voy a ir complicándolo de a poco


*12345678901234567890123456789

NUMEROS   PPIO      3
          WTORPC    'Escriba el numero 1 :',NUM1
          WTORPC    'Escriba el numero 2 :',NUM2

          WTO       NUM1
          WTO       NUM2

          CHAU

NUM1      DS        CL3
NUM2      DS        CL3


          END

 

 

WTORPC Sirve para que escriba algo en pantalla y que a continuación aparezca un valor a introducir por el teclado.

WTORPC 'Escriba el numero 1 :',NUM1

Hay que definir NUM1 y NUM2

Para eso escribo un rótulo NUM1 y pongo DS que significa Define Storage y a continuación escribo CL3 que significa carácter de longitud 3

Cuando ejecuto el programa me deja poner hasta 3 caracteres, y si pongo CL6 me deja poner hasta 6 caracteres.

Los WTO imprimen en pantalla los valores ingresados.

WTOR y WTORPC son muy similares, la diferencia está en que WTORPC se queda esperando a que pulsemos enter, mientras que WTOR cuando se completa la capacidad definida para el rótulo sigue como si hubiéramos pulsado el enter. Lo que si pude ver es que si le pongo acentos en la cadena de texto a presentar en pantalla me da error.


DATOS

F  Palabra (word)
D  Doble palabra
C  Carácter
P  Empaquetado
X  Hexadecimal
B  Binario

DC Define Constant (Guarda un dato)

DS Define Storage (Guarda lugar para los datos)

L Longitud

DC C'Hola'     *Define una cadena de caracteres con contenido Hola
DC CL4'Hola'   *Define cadena de caracteres de longitud 4 con cont Hola
DC CL5'Hola'   *Define cadena de caracteres de longitud 5 con cont Hola
DC 2CL4'Hola'  *Repite dos veces CL4'Hola' y la segunda queda después de la primera.

DS CL4         *Guarda un lugar para una cadena de longitud 4

DC P'298'      *Guarda en formato empaquetado el número 298 |29|8C|
DC P'-298'     *Guarda en formato empaquetado el número -298 |29|8D|


DC P'1475'    *Guarda en formato empaquetado el número 1475 |01|47|5C| Los 0s quedan a la izquierda.

DC PL3'298'   *|00|29|8C|
DC PL2'1475'  *|47|5C| Quedó truncado por ser más largo que la longitud dada.
              Los números los trunca por la izquierda.

DC 2PL3'-45'  *|00|04|5D|00|04|5D| quedan de manera contigua en memoria.

DC X'898'     *Lo guarda en formato hexadecimal |08|98|
DC XL4'898'   *|00|00|08|98|

DC B'101010101' *Lo guarda en formato binario. |01|55|

DC F'16'      *Lo guarda en formato palabra (4 bytes) |00|00|00|10| 16 en base 16 es 10


Arreglos

FECHA DS 0CL8
DIA   DS CL2
MES   DS CL2
ANIO  DS CL4

Para armarlos debo definir uno con el 0 por delante y después con los demás debo completar los bytes con lo que compone el registro. 2 + 2 + 4 = 8

 


Comparación de valores


*12345678901234567980123456789

COMPARA   PPIO 3
          WTO       MENSAJE1
          WTORPC    MENSAJE2,VAL1
          WTORPC    MENSAJE3,VAL2
          CLC       VAL1,VAL2
          BH        MAYOR
          BE        IGUAL
          WTO       'VAL1 ES INFERIOR'
          B         FIN
MAYOR     WTO       'VAL1 ES MAYOR'
          B         FIN
IGUAL     WTO       'AMBOS SON IGUALES'

FIN       CHAU

MENSAJE1  DC        C'BIENVENIDO AL COMPARADOR!!!'
MENSAJE2  DC        C'PRIMER VALOR:'
MENSAJE3  DC        C'SEGUNDO VALOR:'
VAL1      DS        C
VAL2      DS        C


          END


 

Con CLC hago una comparación lógica de dos cadenas de caracteres.

CLC D1(L1,B1),D2(B2)  (dos direcciones de memoria, en este caso remplazas con rótulos)

B Branch (Bifurcar)

BC M1,D2(X2,B2)   M1 Mask (Un codigo, ver tabla)

El resultado analizado es en función de la última comparación.

Existen dos formas de escribirlas

Usando la máscara (codigo de condicion) o por su nombre
 

BC 2,MAYOR BH MAYOR (HIGHER)
BC 4,MENOR BL MENOR (LOWER)
BC 8,IGUAL BE IGUAL (EQUAL)
BC 13,NOMAYOR BNH NOMAYOR (NOT HIGHER)
BC 11,NOMENOR BNL NOMENOR (NOT LOWER)
BC 7,NOIGUAL BNE NOIGUAL (NOT EQUAL)
BC 1,OVERFLOW B0 OVERFLOW (OVERFLOW)
BC 15,SIEMPRE B SIEMPRE (BIFURCACION INCONDICIONAL)
BC O,NUNCA BOP NUNCA (NO OPERATION)

En caso de que se de la condición, bifurcan al rótulo (dirección de memoria indicada).

BCR

BCR es la versión del BC para bifurcar a la dirección contenida en un registro

BCR M1,R1


*12345678901234567980123456789

COMPARA   PPIO 3
          WTO       MENSAJE1
          WTORPC    MENSAJE2,VAL1
          WTORPC    MENSAJE3,VAL2
          LA        7,MAYOR
          LA        8,IGUAL
          CLC       VAL1,VAL2
          BCR       2,7
          BCR       8,8
          WTO       'VAL1 ES INFERIOR'
          B         FIN
MAYOR     WTO       'VAL1 ES MAYOR'
          B         FIN
IGUAL     WTO       'AMBOS SON IGUALES'

FIN       CHAU

MENSAJE1  DC        C'BIENVENIDO AL COMPARADOR!!!'
MENSAJE2  DC        C'PRIMER VALOR:'
MENSAJE3  DC        C'SEGUNDO VALOR:'
VAL1      DS        C
VAL2      DS        C


          END


 

 


BCT - Branch on count

BCT R1,D2(X2,B2)

El BCT es un contador que va a bifurcar tantas veces al rótulo hasta que el valor del registro utilizado por BCT sea 0. Cada vez que se ejecuta BCT decrementa en 1 el valor del registro.

Sirve para hacer bucles del tipo FOR.


*12345678901234567980123456789

COMPARA   PPIO      3

          LA        7,6
BUCLE     WTO       'IMPRESION'
          BCT       7,BUCLE
          WTO       'FIN BUCLE'

FIN       CHAU

          END

 

LA 7,6 Carga el valor 6 en el registro 7.

Se va a imprimir 6 veces la palabra impresión.

IMPRESION
IMPRESION
IMPRESION
IMPRESION
IMPRESION
IMPRESION
FIN BUCLE

Otro parecido al BCT es el BCTR que usa la dirección contenida en un registro.

BCTR R1,R2


*12345678901234567980123456789

PROGRAMA  PPIO      3

          LA        7,6
          LA        8,BUCLE
BUCLE     WTO       'IMPRESION'
          BCTR      7,8
          WTO       'FIN BUCLE'

FIN CHAU

END

 

El resultado de este algoritmo es exactamente igual que el anterior.

C Compare

C R1,D2(X2,B2)

Compara el valor del registro con el valor contenido en una dirección de memoria. Debe estar en formato palabra.


*12345678901234567890123456789

EJ1       PPIO      3
          LA        7,4
          C         7,NUM1
          BE        IGUALES
          WTO       'SON DIFERENTES'
          B         FIN
IGUALES   WTO       'SON IGUALES'

FIN       CHAU

NUM1      DC        F'3'

          END

 

 


MVC

MVC D1(L1,B1),D2(B2)

El mvc copia el contenido de una dirección de memoria a otra. La cantidad de bytes a copiar se indican con L1, sino se utiliza la longitud del rótulo. Copia del segundo rótulo hacia el primero, si la longitud del rotulo 2 > long rotulo 1 se seguirán copiando los caracteres pisando la memoria contigua.


*12345678901234567980123456789

COMPARA   PPIO      3

          WTOR      'INGRESE NUMERO:',NUM1
          MVC       NUM2,NUM1
          WTO       NUM2


FIN       CHAU

NUM1      DS        C'2'
NUM2      DS        C'2'

          END

 

NUM2 tendrá los caracteres copiados de NUM1.

MVC me sirve para imprimir con el WTO a lo que apunta la dirección de algún registro.


*12345678901234567980123456789

EJ1       PPIO      3
          LA        4,PALAB1
          MVC       PALAB2,0(4)
          WTO       PALAB2

FIN       CHAU

PALAB1    DC        CL3'123'
PALAB2    DS        CL3

          END

 

Como MVC usa direcciones, cargo en el registro 4 la dirección de PALAB1. MVC copia el contenido a PALAB2 y WTO lo imprime.

Como PALAB1 tenía CL3'123', el programa imprime 123 en pantalla. ¬°Gran programa por cierto!


LA (Load Address)

LA R1,D2(X2,B2)

Carga una dirección de memoria en el registro.

En el ejemplo anterior cargo la dirección de PALAB1. Esa dirección luego la usa MVC para hacer la copia de los caracteres a PALAB2.

También puedo usar LA para ponerle directamente un valor numérico al registro.


LA 5,0    * Pone en 0 el registro 5
LA 6,18   * Le pone 18 al valor contenido en el registro 6
LA 7,NUM1 * El valor del registro ahora será la dirección de NUM1

 

Con LA se puede hacer también un contador.


         LA 8,0

BUCLE    LA 8,1(8)

         {alguna comparación}

         B 2,BUCLE
 

El desplazamiento va a ir agregándole una "posición" cada vez que pase, por lo que se puede usar como un contador.


UNPK (Unpack)

UNPK D1(L1,B1),D2(L2,B2) L1 y L2 son longitudes

Desempaqueta la segunda dirección y lo guarda en la primera.

UNPK NUEVOVAL,VALEMP

Transforma un valor guardado en formato empaquetado en uno zoneado.

F1F2D3 <-- 123D


PACK

UNPK D1(L1,B1),D2(L2,B2) L1 y L2 son longitudes

Hace lo contrario de UNPK


MVZ (Move Zones)

MVZ D1(L1,B1),D2(B2)

Mueve toda una zona de longitud L1, o si no se especifica una longitud, se toma la longitud del primer rótulo. Se copia del segundo rótulo hacia el primero, si la longitud es mayor que la del rótulo, los caracteres seguirán copiándose pisando la memoria contigua.


Imprimir el valor de un empaquetado en memoria.


PROG      PPIO     3

          LA       5,NUM
          UNPK     CAR,0(8,5)
          MVZ      CAR+7(1),=X'FF'
          WTO      CAR

FIN       CHAU

NUM       DC       PL8'12345678'
CAR       DC       CL8'1'

          END
 

Como quedó en formato zoneado, necesito sacarte el signo y remplazarlo con una F, para que quede en formato EBCDIC, por eso se hace el MVZ que significa Move Zone

Si el número queda F1F2D2 con el MVZ reemplazo la D con una F, y después lo imprimo con WTO.


ZAP (Zero and Add Package)

ZAP D1(L1,B1),D2(L2,B2)

Pone en 0 el empaquetado 1 y le suma el empaquetado 2.

Usarlo para mover empaquetados.

*12345678901234567890123456789

EJ1       PPIO      3

          ZAP       NUM2,NUM1

          UNPK      NUMCHAR,NUM2

          MVZ       NUMCHAR+2(1),=X'FF'

          WTO       NUMCHAR


          CHAU

NUM1      DC        PL3'351'
NUM2      DC        PL3'999'
NUMCHAR   DS        CL3


END

 

Imprime en pantalla 351.


AP (Add Package)

AP D1(L1,B1),D2(L2,B2)

Suma dos empaquetados.

 

SP (Substract Package)

SP D1(L1,B1),D2(L2,B2)

Resta dos empaquetados.

 

El resultado de la resta queda en el primer empaquetado.


*12345678901234567890123456789

EJ1       PPIO      3

SUMA      AP        NUM1,NUM2

          UNPK      NUMAUX,NUM1
          MVZ       NUMAUX+2(1),=X'FF'

          WTO       'VALOR SUMA:'
          WTO       NUMAUX


RESTA     SP        NUMR1,NUMR2
          UNPK      NUMAUXR,NUMR1
          MVZ       NUMAUXR+2(1),=X'FF'

          WTO       ' '
          WTO       'VALOR RESTA:'
          WTO       NUMAUXR

FIN       CHAU

NUM1      DC        PL3'123'
NUM2      DC        PL3'321'
NUMAUX    DC        CL3'1'

NUMR1     DC        PL3'250'
NUMR2     DC        PL3'150'
NUMAUXR   DC        CL3'1'

          END
 

En pantalla sale:

VALOR SUMA:
444

VALOR RESTA:
100


 

 

mail: [email protected]