Você está na página 1de 11

B

INTRODUCCIN AL LENGUAJE
ENSAMBLADOR DE SPARC

B.1.

Introduccin

En este apndice se estudiarn las caractersticas especcas del lenguaje ensamblador para
los procesadores con arquitectura SPARC.
Aunque este ensamblador se asemeja mucho a otros, tiene algunas caractersticas especcas; por ejemplo, en el ensamblador de SPARC las constantes inmediatas no requieren ningn
smbolo especco y las referencias a memoria van entre corchetes, tanto si provienen de etiquetas como de registros.

B.2.

Smbolos y expresiones

Se denominan smbolos a los nombres que representan a diversas entidades. Estos nombres
se materializan en cadenas de caracteres con las limitaciones usuales en otros lenguajes de
programacin (no comenzar por un nmero, no contener ciertos caracteres especiales, etc.).
Segn una primera clasicacin, los smbolos pueden ser:
Permanentes: son smbolos que representan en todos los programas a las mismas entidades. De
este tipo son los nombres de los registros y los operadores, estos smbolos se caracterizan
por comenzar por el carcter %.
Denidos por el usuario: son smbolos que tienen una signicacin especca en cada programa: constantes, direcciones, nombres de procedimientos, etc.
Los smbolos denidos por el usuario toman valor cuando el programa se compila y en el
momento de la ejecucin quedan sustituidos por el valor al que representan que es inalterable.
La forma de asignar valores a los smbolos se efecta de forma distinta en funcin de lo que
representen:
231

Introduccin al lenguaje ensamblador de SPARC

232

1. Pueden ponerse como una etiqueta en algn punto del programa, en este caso el smbolo
representa la direccin de la instruccin o dato que vaya a continuacin. Las etiquetas se
caracterizan por ir al principio de la lnea y seguidas por dos puntos (:).
Para asignar valor a este tipo de smbolos el ensamblador lleva una variable interna denominada location counter (LC) (contador de direccin). Este contador se inicializa a 0
al comenzar la compilacin y se incrementa por el nmero de bytes necesarios para cada
instruccin mquina traducida o cada rea reservada para datos. Dicho de otra forma, el
LC lleva un control de la direccin de memoria de cada dato o instruccin pero relativa
al principio del programa. Cuando aparece una etiqueta el compilador le asigna el valor
que tenga LC en ese momento. Este valor ser una referencia, ya que el valor real de la
direccin representada por las etiquetas ser el valor del LC en el momento de compilar
esa lnea ms la direccin de comienzo de programa. A los smbolos asignados de esta
forma se les denomina smbolos relocalizables.
2. Pueden asignarse tambin mediante el signo =, en este caso el smbolo toma el valor de lo
que haya a la derecha del signo = que debe ser constante. Despus del signo = puede haber
algo ms que una simple constante numrica, es decir, puede aparecer una expresin.
Una expresin en una combinacin de constantes y smbolos relacionados mediante operadores aritmticos entre los cuales los ms usuales son: +, -, *, / (divisin entera). Tambin
existen, como operadores unitarios, el - y los siguientes:

%uhi: Extrae los bits 63 a 42 del argumento


%ulo: Extrae los bits 41 a 32 del argumento
%hi: Extrae los bits 31 a 10 del argumento
%lo: Extrae los bits 9 a 0 del argumento
Para estos operadores el argumento se pone entre parntesis. Estos operandos son especialmente
tiles para la instruccin sethi que sirve para cargar los 22 bits ms altos de un registro.
Uno de los trminos que pueden aparecer en las expresiones es el valor del LC en el momento de compilarse la expresin que se representa por un punto (.). Esto es muy habitual cuando
se quiere tener en una constante la longitud de una cadena ya que se toma el valor del LC despus de reservar su espacio y se le resta el smbolo que represente la direccin de comienzo de
la cadena. La base en que se interpretan las constantes sigue las mismas convenciones que el
lenguaje C.
Es necesario dejar bien claro que las expresiones que dan valores a los smbolos se evalan cuando el programa se compila y por tanto todos los trminos que en ellas aparecen
deben estar previamente denidos. Por ello estas expresiones y las que aparecen en los lenguajes de alto nivel no tienen casi nada en comn.

B.2.1.

Tipos de smbolos

Abundando en lo anteriormente expuesto, los smbolos pueden clasicarse en funcin de su


valor en dos clases:

B.3. Tipos de instrucciones

233

Absolutos: Son smbolos cuyo valor es constante independientemente del lugar de memoria
donde se site el programa.
Relocalizables: Son smbolos cuyo valor depende de la posicin del programa en memoria.
Esta clasicacin es aplicable tambin a las expresiones.
Otra clasicacin afecta a la visibilidad del smbolo, es decir el mbito donde el smbolo es
reconocido. Atendiendo a este criterio los smbolos se pueden clasicar en:
Locales: Slo se reconocen en el chero fuente actual que normalmente contendr uno o varios
procedimientos.
Externos o referencias no resueltas: Son smbolos que no estn denidos en el programa,
normalmente corresponden a procedimientos o constantes que radican en libreras. Estos
smbolos son localizados por el montador que es quien al nal da valores a estos smbolos.

B.3.

Tipos de instrucciones

En el ensamblador de SPARC existen 3 tipos de instrucciones:


Directivos, que son rdenes dirigidas especcamente al compilador, en la nomenclatura de
SPARC a los directivos tambin se les llama pseudo-operaciones. Se caracterizan porque
todos ellos comienzan con un punto. Evidentemente, los directivos pueden cambiar segn
el compilador de ensamblador que se emplee, su versin, etc.
Instrucciones mquina, son las instrucciones que se traducen literalmente a cdigo mquina.
Estas instrucciones son la que aparecen en el juego de instrucciones de la mquina (ver
apndice A). Hay que tener en cuenta que el compilador de ensamblador no reordena las
instrucciones para las bifurcaciones retardadas, ni para evitar las dependencias de datos;
por ello, estas reordenaciones hay que hacerlas a mano. Tambin hay que mencionar que,
en el lenguaje ensamblador de SPARC, el operando destino siempre es el ltimo.
Instrucciones sintticas, son instrucciones similares a las de la mquina pero que no existen en
realidad. Es el compilador el que traduce cada instruccin sinttica por otra equivalente
a partir del conjunto de instrucciones mquina. Estas instrucciones existen para facilitar
la programacin y la legibilidad de los programas. Evidentemente, las instrucciones sintticas pueden depender del compilador de ensamblador que se utilice, sin embargo suele
haber bastante consenso en su utilizacin. En la tabla B.1 se muestran las instrucciones
sintticas empleadas en el ensamblador para arquitecturas SPARC.
Tambin, como en otros lenguajes, existe la posibilidad de incorporar comentarios, esto
puede hacerse de dos formas:
Para los comentarios que ocupan varias lneas, puede emplearse la sintaxis del lenguaje
C, es decir, abriendo el comentario con /* y cerrndolo con */.
Si el comentario ocupa una lnea, o slo su parte nal, basta con iniciarlo con el signo !.

234

Introduccin al lenguaje ensamblador de SPARC

Tabla B.1. Instrucciones sintticas del lenguaje ensamblador de SPARC (contina).


Instruccin sinttica
mov a, rd
clr rd
clrb [direccin]
clrh [direccin]
clr [direccin]
clrx [direccin]
clruw rs1, rd
clruw rd
inc rd
inc inmed., rd
inccc rd
inccc inmed, rd
dec rd
dec inmed., rd
deccc rd
deccc inmed., rd
not rs1, rd
not rd
neg rs1, rd
neg rd
signx rd
signx rs1, rd
btst a, rs1
bset a, rd
bclr a, rd
btog a, rd
tst rs1
cmp rs1, a
jmp direccin
call direccin

Equivalencia
or %g0, a, rd
or %g0, %g0, rd
stb %g0, [direccin]
sth %g0, [direccin]
stw %g0, [direccin]
stx %g0, [direccin]
srl rs1, %g0, rd
srl rd, %g0, rd
add rd, 1, rd
add rd, inmed., rd
addcc rd, 1, rd
addcc rd, inmed., rd
sub rd, 1, rd
sub rd, inmed., rd
subcc rd, 1, rd
subcc rd, inmed., rd
xnor rs1, %g0, rd
xnor rd, %g0, rd
sub %g0, rs1, rd
sub %g0, rd, rd
sra rd, %g0, rd
sra rs1, %g0, rd
andcc rs1, a, %g0
or rd, a, rd
andn rd, a, rd
xor rd, a, rd
orcc %g0, rs1, %g0
subcc rs1, a, %g0
jmpl direccin, %g0
jmpl direccin, %o7

ret
retl
restore
iprefetch etiqueta

jmpl %i7+8, %g0


jmpl %o7+8, %g0
restore %g0, %g0, %g0
bn,a,pt %xcc etiqueta

1 En

Comentarios
a rd 1
Pone el registro a 0
Pone un byte de memoria a 0
Pone media palabra de memoria a 0
Pone una palabra de memoria a 0
Pone una doble palabra de memoria a 0
Borra la palabra alta de rs1 y queda en rd
Borra la palabra alta
Incrementa en 1
Incrementa en una constante
Incrementa en 1 cambiando los ags
Incrementa en constante cambiando ags
Decrementa en 1
Decrementa en una constante
Decrementa en 1 cambiando los ags
Decrementa en constante cambiando ags
Complementa a 1 rs1 y queda en rd
Complementa a 1
Complementa a 2 rs1 y queda en rd
Complementa a 2
Extiende el signo de 32 a 64 bits
Extiende signo de rs1 a rd (32 a 64 bits)
Anlisis de bit (bit test) 1
Puesta a 1 de bit (bit set) 1
Puesta a o de bit (bit clear ) 1
Complemento de bit (bit toggle) 1
Prueba de un operando (cambia ags)
Comparacin (cambia ags) 1
Salto ordinario
(Diere de la instruccin call en el
modo de direccionamiento de la
direccin del procedimiento)
Retorno de subrutina
Retorno de subrutina nal
Restore ordinario
Carga instruccin en cach

estas instrucciones a puede ser un registro o una constante inmediata.

B.4. Directivos del ensamblador

235

Tabla B.1. Instrucciones sintticas del lenguaje ensamblador de SPARC (conclusin).


Instruccin sinttica
setuw valor, rd
(o set valor, rd)

setsw valor, rd

setx valor, r, rd

Equivalencia
sethi %hi(valor), rd

Comentarios
(valor0x3FF= 0)

or %g0, valor, rd

(valor [0, 4095])

sethi %hi(valor), rd;


or rd, %lo(valor), rd
sethi %hi(valor), rd

(otros casos)

or %g0, valor, rd

(valor [-4096, 4095])

sethi %hi(valor), rd;


sra rd, %g0, rd

(valor < 0)&(valor 0x3FF=0)

sethi %hi(valor), rd;


or rd, %lo(valor), rd

(otros casos con valor 0)

sethi %hi(valor), rd;


or rd, %lo(valor), rd;
sra rd, %g0, rd
sethi %uhi(valor), r;
or r, %ulo(valor), r;
sllx r, 32, r;
sethi %hi(valor), rd;
or rd, r, rd;
or rd, %lo(valor), rd

(otros casos con valor < 0)

(valor 0)&(valor 0x3FF=0)

Transere una constante


de 64 bits a un registro.

Nota:
Las instrucciones sintticas que se sustituyen por varias instrucciones no deben
situarse en un ciclo adelantado detrs de una instruccin de control de ujo.

B.4.

Directivos del ensamblador

Los directivos del ensamblador de SPARC estn bastante inspirados en los del MACRO-11
de DEC. Los clasicaremos segn la funcin que realizan.

B.4.1.

Principio del programa. Segmentos

Un programa en ensamblador de SPARC debe tener, al menos, dos segmentos: el de cdigo


y el de datos. El segmento de datos se identica porque comienza por el directivo:

.data
Anlogamente el segmento de cdigo debe comenzar con el directivo:

236

Introduccin al lenguaje ensamblador de SPARC

.text
Si el programa se va a ejecutar directamente desde el sistema operativo (UNIX normalmente), deber ponerse una etiqueta denominada main en el lugar donde se desee que comience la
ejecucin (direccin de transferencia). La direccin relocalizable representada por main es la
que se cargar en el contador de programa cuando el sistema operativo le pase el control. Esta
etiqueta tiene que declararse como global para que sea identicada desde fuera del programa.
Esta declaracin debe ponerse antes de la denicin de la direccin. Esto se hace mediante el
directivo:

.global main
Este directivo tambin debe usarse cuando se programan funciones o procedimientos a los
que se pueda llamar desde fuera de nuestro programa, y en general, cuando un smbolo deba
reconocerse desde el exterior del programa. En este caso, se pueden poner todos los smbolos
afectados en un mismo directivo .global separndolos por comas.

B.4.2.

Reserva de espacio en memoria

El ensamblador de SPARC permite reservar espacio por bloques con el directivo:

.skip n
donde n es el nmero de bytes que se quieren reservar. Este directivo causa que el LC se
incremente en n.
Para reservar espacio inicializado de variables escalares utilizaremos los directivos .byte,
.half, .word, .xword, .single, .double o .quad en funcin del tipo de dato que queramos
inicializar: byte, media palabra (16 bits), palabra (32 bits), palabra extendida (64 bits), nmeros
en punto otante en simple, doble o cudruple precisin, respectivamente.
La sintaxis de estos directivos es la siguiente:

.byte

.half

.word

.xword

.single

.double

v1 [, v2 , ....]

.quad

aqu v1 , v2 , etc. representan los valores a los que se inicializa la unidad de almacenamiento
especicada. Se pueden especicar uno o ms valores para la inicializacin, reservndose tantas
unidades del tipo especicado como valores se indiquen.
Las mquinas con arquitectura SPARC exigen alineacin para todos los tipos de datos, lo
que supone que antes de la mayora de los directivos anteriores el LC debe estar alineado. Para
conseguir la alineacin basta incluir el directivo

B.5. Operaciones de entrada y salida

237

.align n
que fuerza a que el LC sea mltiplo de n, dejando algunos bytes a 0.
La alineacin del cdigo tambin es necesaria, sin embargo, no hace falta emplear el directivo .align ya que .text alinea automticamente la primera instruccin, y por tanto todas las
dems, a 4.
Para reservar espacio para cadenas de caracteres podra emplearse el directivo .byte con
los cdigos ASCII de los caracteres de la cadena pero son ms tiles los directivos .ascii y
.asciz cuya sintaxis es la siguiente:

.ascii
.asciz

"cadena de caracteres 1" [,"cadena de caracteres 2"...]

Ambos directivos guardan en bytes sucesivos los cdigos ASCII de los caracteres que se
indican. La diferencia entre ambos es que .ascii reserva espacio estrictamente para las cadenas
de caracteres que se indican y .asciz hace lo mismo, pero terminando cada una de las cadenas
con un byte nulo.

B.5.

Operaciones de entrada y salida

Las operaciones de entrada y salida en ensamblador se pueden efectuar de forma sencilla


mediante las funciones putchar y getchar (las mismas que se emplean en los programas escritos
en lenguaje C).
Una llamada a getchar devuelve, en el byte ms bajo del registro o0, el cdigo ASCII del
ltimo carcter pulsado en el terminal stdin, aunque hay que pulsar la tecla de retorno de carro
al nal de la cadena que se introduzca.
Para escribir un carcter en la pantalla del terminal stdout, basta depositar, en el byte de
orden ms bajo del registro o0, el cdigo ASCII del carcter que se quiera imprimir y llamar a
la funcin putchar.
A partir de estas funciones se pueden construir otras que lean o que escriban cadenas completas, que lean o escriban nmeros (para lo que habr que hacer las conversiones pertinentes),
etc.

B.6.

Pasos para la ejecucin de un programa

Para conseguir la ejecucin de un programa escrito en lenguaje ensamblador de SPARC,


despus de editarlo, con la extensin ".s", hay que compilarlo con el siguiente comando:

gcc -g -Wa,-xarch=v8plus chero_fuente -o chero_ejecutable


Despus de eso el chero ya puede ejecutarse desde la lnea de comandos.

238

Introduccin al lenguaje ensamblador de SPARC

LF=10

.data
mensaje:.ascii "Introduzca una cadena: "
L=.- mensaje
cadena: .skip 80
.text
.global main
main:
save %sp,-64, %sp
/* Impresin del mensaje */
sethi %hi(mensaje), %o0
or %o0, %lo(mensaje), %o0
or %g0, L, %o1
call imprime_cadena
/* Lectura de la cadena */
or %g0, %g0, %l1

bucle1:

sethi %hi(cadena), %l0


or %l0, %lo(cadena), %l0

call getchar
nop
stb %o0,[ %l0+ %l1]
subcc %o0,LF, %g0
bne bucle1
add %l1, 1, %l1
/* Impresin de la cadena */
or %g0, %l0, %o0
or %g0, %l1, %o1
call imprime_cadena
nop
jmpl %i7+8, %g0
restore %g0, %g0, %g0
imprime_cadena:

bucle:

save %sp, -64, %sp


or %g0, %g0, %l1
ldub [ %i0 + %l1], %o0
call putchar
add %l1, 1, %l1
subcc %i1, 1, %i1
bne bucle
nop
jmpl %i7+8, %g0
restore %g0, %g0, %g0

! ASCII fin de lnea (line feed)=10

! o0 contiene la direccin de
! comienzo del mensaje
! o1 contiene su longitud
!
!
!
!

CICLO ADELANTADO A call


Inicializacin del ndice
l0 contiene la direccin de
comienzo de la cadena

!
!
!
!
!
!

Lee carcter y lo deposita en o0


CICLO ADELANTADO
Almacena carcter
Comparacin con LF (fin de cadena)
Condicin de final
CICLO ADELANTADO

! o0 contiene la direccin de
! comienzo de la cadena
! o1 contiene su longitud
! CICLO ADELANTADO
! Devuelve el control al S.O. (ret)
! en i0 tenemos la direccin de la cadena
! y en i1 su longitud
! l1 es el ndice
!
!
!
!
!
!
!

Extrae el carcter de memoria


Imprime el carcter contenido en o0
CICLO ADELANTADO
Actualizan los ndices
Condicin de final del bucle
CICLO ADELANTADO
Retorno

Fig. B.1. Programa en lenguaje ensamblador de SPARC para leer una cadena de caracteres y escribirla.

B.6. Pasos para la ejecucin de un programa

LF=10

.data
mensaje:.ascii "Introduzca una cadena: "
L=.- mensaje
cadena: .skip 80
.text
.global main
main:
save %sp,-64, %sp
/* Impresin del mensaje */
set mensaje, %o0
mov L, %o1
call imprime_cadena
/* Lectura de la cadena */
clr %l1
set cadena, %l0
bucle1:

call getchar
nop
stb %o0,[ %l0+ %l1]
cmp %o0,LF
bne bucle1
inc %l1
/* Impresin de la cadena */
mov %l0, %o0
mov %l1, %o1
call imprime_cadena
nop
ret
restore

imprime_cadena:

bucle:

save %sp, -64, %sp


clr %l1
ldub [ %i0 + %l1], %o0
call putchar
inc %l1
deccc %i1
bne bucle
nop
ret
restore

239

! ASCII fin de lnea (line feed)=10

! o0 contiene la direccin de
! comienzo del mensaje
! o1 contiene su longitud
!
!
!
!

CICLO ADELANTADO a call


inicializacin del ndice
l0 contiene la direccin de
comienzo de la cadena

!
!
!
!
!
!

lee carcter y lo deposita en o0


CICLO ADELANTADO
Almacena carcter
LF=fin de cadena
Condicin de final
CICLO ADELANTADO

! o0 contiene la direccin de
! comienzo de la cadena
! o1 contiene su longitud
! CICLO ADELANTADO
! Devuelve el control al S.O.
! en i0 tenemos la direccin de la cadena
! y en i1 su longitud
! l1 es el ndice
!
!
!
!
!
!

Extrae el carcter de memoria


Imprime el carcter contenido en o0
CICLO ADELANTADO
Actualizan los ndices
Condicin de final del bucle
CICLO ADELANTADO

Fig. B.2. Programa en lenguaje ensamblador de SPARC para leer una cadena de caracteres y escribirla. Este programa hace uso de instrucciones sintticas

240

B.7.

Introduccin al lenguaje ensamblador de SPARC

Ejemplo de programacin

En esta seccin veremos un ejemplo de programa completo. El ejemplo que proponemos pide una cadena por teclado y luego la imprime por pantalla. El programa est autodocumentado
para facilitar su comprensin. En una primera versin no emplearemos las instrucciones sintticas (gura B.1). En la versin ms evolucionada de la gura B.2 se muestra el mismo programa
pero utilizando instrucciones sintticas. Como puede verse, esta ltima versin es muchsimo
ms legible que la anterior.

Bibliografa y referencias
PAUL , R.P. 2000. SPARC Arquitecture, Assembly Language Programming & C. 2 edn. Prentice-Hall.
W EAVER , D.L., & G ERMOND , T. ( EDITORES ). 1994. The SPARC Architecture Manual, version 9.
Prentice-Hall International.

CUESTIONES Y PROBLEMAS
B.1 Escribir una versin del programa de ejemplo citado en el texto que efecte la lectura de
la cadena por teclado mediante una funcin. Esta funcin debe depositar la cadena leda
a partir de la direccin de memoria especicada en su registro i0 (o0 para los programas
que la llamen) y devolver la longitud de la cadena leda en su registro i1 (o1 para los
programas que la llamen).
B.2 Escribir una nueva versin de la funcin citada en el problema anterior que almacene en
memoria la cadena terminada con un carcter nulo. El segundo parmetro (i1) debe tener
una doble funcin: actuando como parmetro de entrada, recibir el nmero mximo de
caracteres que se espera en la cadena, y, como parmetro de salida, devolver el nmero
de caracteres realmente ledo.
B.3 Escribir una funcin en lenguaje ensamblador de SPARC que escriba en la pantalla del
terminal la cadena que se encuentra en memoria a partir de la direccin especicada en
su registro i0 (o0 para los programas que la llamen). La funcin debe escribir caracteres
hasta que se encuentre un carcter nulo.
B.4 Construir una versin de la funcin de escritura de cadena, mencionada en el problema
anterior, en que la escritura de la cadena termine, bien cuando se encuentre un carcter
nulo, o bien cuando se complete el nmero de caracteres especicado en el registro i1 (lo
que ocurra antes).

Cuestiones y problemas

241

B.5 Haciendo uso de algunas de las funciones escritas en los problemas anteriores, escribir
un programa, en lenguaje ensamblador de SPARC, que lea una cadena de caracteres del
teclado del terminal, la almacene en memoria y luego la escriba por pantalla pasada a
maysculas.
B.6 Escribir una funcin, en lenguaje ensamblador de SPARC, que tome una cadena cuya
direccin se especique en el registro i0 (o0 para los programas que la llamen), la interprete como un nmero en hexadecimal y deposite ese nmero en el registro i1 (o1 para
los programas que la llamen).
B.7 Escribir una funcin, en lenguaje ensamblador de SPARC, que escriba a partir de la direccin dada por el registro i1, una cadena que represente el valor del contenido de su
registro i0 (o0 para los programas que la llamen) en hexadecimal.
B.8 Utilizando las funciones de los problemas anteriores, escribir un programa en lenguaje
ensamblador de SPARC que pida por teclado un nmero hexadecimal y escriba por la
pantalla, tambin en hexadecimal, el doble de ese nmero.
B.9 Escribir una funcin en ensamblador de SPARC con dos parmetros. La funcin debe
extraer de la cadena que comienza en la direccin especicada por el primer parmetro
un nmero, interpretarlo en decimal y devolver el valor obtenido en el segundo parmetro. Se puede suponer que la cadena especicada por el primer parmetro slo contiene
caracteres numricos.
B.10 Escribir una funcin en ensamblador de SPARC con dos parmetros. La funcin debe
devolver, en la direccin especicada por el primer parmetro, una cadena que contenga
el valor del segundo parmetro escrito en decimal.
B.11 Empleando algunas de las funciones anteriores escribir un programa en lenguaje ensamblador de SPARC que pida por teclado un nmero en hexadecimal y lo escriba por pantalla
en decimal.
B.12 Empleando algunas de las funciones anteriores escribir un programa en lenguaje ensamblador de SPARC que pida por teclado un nmero en decimal y lo escriba por pantalla en
hexadecimal.
B.13 Escribir un programa, en lenguaje ensamblador de SPARC, que pida por teclado un nmero en hexadecimal, lo almacene en un registro, y escriba por pantalla en decimal el
valor del contenido de su byte de orden ms bajo.

Você também pode gostar