JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
SPARC Assembly Language Reference Manual     Oracle Solaris 11.1 Information Library
search filter icon
search icon

Document Information

Preface

1.  SPARC Assembler Syntax

2.  Executable and Linking Format

3.  Directives and Pseudo-Operations

4.  Creating Data in Assembler

5.  SPARC Code Models

6.  Writing Functions -- The SPARC ABI

7.  Assembler Inline Functions and __asm Code

A.  Using the Assembler Command Line

B.  A Sample Assembler Program

C.  SPARC Instruction Sets and Mnemonics

Index

Appendix B

A Sample Assembler Program

The following code takes a sample C language program and generates the corresponding assembly code using the Oracle Solaris Studio C compiler running on the Solaris 11 operating environment. Comments have been added to the assembly code to show correspondence to the C code.

The following C Program computes the first n Fibonacci numbers.

Example B-1 C Program Example Source

#include <stdio.h>
#include <stdlib.h>

/* a simple program computing the first n Fibonacci numbers */

extern unsigned * fibonacci();

#define MAX_FIB_REPRESENTABLE 49

/* compute the first n Fibonacci numbers */
unsigned * fibonacci(n)
     int n;
{
  static unsigned fib_array[MAX_FIB_REPRESENTABLE] = {0,1};
  unsigned prev_number = 0;
  unsigned curr_number = 1;
  int i;

  if (n >= MAX_FIB_REPRESENTABLE) {
    printf("Fibonacci(%d) cannot be represented in a 32 bit word\n", n);
    exit(1);
  }

  for (i = 2; i < n; i++) {
    fib_array[i] = prev_number + curr_number;
    prev_number = curr_number;
    curr_number = fib_array[i];
  }

  return(fib_array);
}

int main()
{
  int n, i;
  unsigned * result;

  printf("Fibonacci(n):, please enter n:\n");
  scanf("%d", &n);

  result = fibonacci(n);
  for (i = 1; i <= n; i++)
    printf("Fibonacci (%d) is %u\n", i, *result);

  return 0;
}

The Oracle Solaris Studio C compiler generates the following assembler output for the Fibonacci number C source. Annotation has been added to help you understand the code.

Example B-2 Assembler Output From C Source

    .section    ".text",#alloc,#execinstr
    .file   "fib.c"

    .section    ".data",#alloc,#write       ! open a data section
                            ! #alloc - memory will be allocated for this section at runtime
                            ! #write - section contains data that is writeable during process execution
Ddata.data:
    .align  4                       ! align the beginning of this section to a 4-byte boundary

.L18:
    .skip   4                       ! skip 4 bytes, which initializes fib_array[0]=0
    .word   1                       ! write the 4-byte value '1', initializes fib_array[1]=1
    .skip   188                     ! skip 188 bytes, which initializes the remainder of fib_array[] to 0
    .type   .L18,#object                ! set the type of .L17 (fib_array) to be an object

Drodata.rodata:
    .section    ".rodata1",#alloc           ! open a read-only data section.
    .align  4

!
! CONSTANT POOL
!

.L21:
    .ascii  "Fibonacci(%d) cannot be represented in a 32 bit word\n\000"    ! ascii string for printf
    .align  4                                   ! align the next ascii string to a 4-byte boundary

.L34:
    .ascii  "Fibonacci(n):, please enter n:\n\000"
    .align  4

.L35:
    .ascii  "%d\000"
    .align  4

.L40:
    .ascii  "Fibonacci (%d) is %u\n\000"

    .section    ".text",#alloc,#execinstr       ! open a text section
/* 000000      0 */     .align  4
/* 000000        */     .skip   16
/* 0x0010        */     .align  4
! FILE fib.c

!    1        !#include <stdio.h>
!    2        !#include <stdlib.h>
!    4        !/* a simple program computing the first n Fibonacci numbers */
!    6        !extern unsigned * fibonacci();
!    8        !#define MAX_FIB_REPRESENTABLE 49
!   10        !/* compute the first n Fibonacci numbers */
!   11        !unsigned * fibonacci(n)
!   12        !     int n;
!   13        !{

!
! SUBROUTINE fibonacci
!
! OFFSET    SOURCE LINE LABEL   INSTRUCTION

            .global fibonacci           ! create a symbol with global scope

            fibonacci:

            .L900000112:
/* 000000     13 */     save    %sp,-96,%sp     ! create a new stack frame and
                            ! register window for this subroutine

!   14        !  static unsigned fib_array[MAX_FIB_REPRESENTABLE] = {0,1};
!   15        !  unsigned prev_number = 0;
!   16        !  unsigned curr_number = 1;
!   17        !  int i;
!   19        !  if (n >= MAX_FIB_REPRESENTABLE) {

/* 0x0004     19 */     cmp     %i0,49      ! cmp is a synthetic instr, equivalent to
                            ! subcc %i0,49,%g0
/* 0x0008        */     bge,pn  %icc,.L77000033 ! branch %i0 (n) on gt 49 to .L77000033 ;
!                                                 predict not taken
/* 0x000c     24 */     cmp     %i0,2       ! delay slot instr. Note that although
                            ! this instr is conceptually executed before the branch, it does
                            ! not influence the condition codes as seen by the branch

!   20        !    printf("Fibonacci(%d) cannot be represented in a 32 bit word\n", n);
!   21        !    exit(1);
!   22        !  }
!   24        !  for (i = 2; i < n; i++) {

            .L77000052:
/* 0x0010     24 */     ble,pn  %icc,.L77000043 ! branch on n less equal to 2 ;  predict not taken
/* 0x0014        */     mov     2,%l4       ! delay slot instr. %l4 = i = 2

            .L77000061:
/* 0x0018     24 */     add     %i0,-1,%l5          ! %l5 = %i0 (n) - 1
/* 0x001c     16 */     mov     1,%i4           ! %i4 (curr_number) = 1
/* 0x0020     15 */     mov     0,%i3           ! %i3 (prev_number) = 0
/* 0x0024        */     sethi   %hi(.L18),%i1       ! set the high 22-bits of %i1 to the address of .L18
                                ! (fib_array)
            .L900000109:
/* 0x0028     15 */     add     %i1,%lo(.L18),%i0       ! complete the formation of the address of fib_array

!   25        !    fib_array[i] = prev_number + curr_number;

/* 0x002c     25 */     add     %i3,%i4,%l7         ! %i7 = %i3 (prev_number) + %i4 (curr_number)
/* 0x0030     15 */     add     %i0,8,%l6           ! %l6 = &fib_array[i]

            .L900000110:
                                ! beginning of the loop body
/* 0x0034     24 */     add     %l4,1,%l4           ! increment i by 1

!   26        !    prev_number = curr_number;

/* 0x0038     26 */     mov     %i4,%i3         ! %i3 (prev_number) = %i4 (curr_number)
/* 0x003c     25 */     st      %l7,[%l6]           ! store %l7 into fib_array[i]

!   27        !    curr_number = fib_array[i];

/* 0x0040     27 */     mov     %l7,%i4         ! %i4 (curr_number) = %l7 (fib_array[i])
/* 0x0044     24 */     add     %l6,4,%l6       ! increase %l6 by 4 bytes, so that it now contains &fib_array[i+1]
/* 0x0048        */     cmp     %l4,%l5         ! i <= (n - 1)
/* 0x004c        */     ble,pt  %icc,.L900000110    ! if yes (predict taken), goto beginning of loop
/* 0x0050     25 */     add     %i3,%i4,%l7     ! delay slot instr. %i7 = %i3 (prev_number) + %l4 (curr_number)
                                ! end of loop body

!   28        !  }
!   30        !  return(fib_array);

                                ! Body of if (n >= MAX_FIB_REPRESENTABLE) {}
            .L77000043:
/* 0x0054     30 */     sethi   %hi(.L18),%i5       ! set the high 22-bits of %l4 to the address of .L18
                                ! (fib_array)
/* 0x0058     24 */     ret                 ! synthetic instr.  equivalent to jmpl %i7+8, %g0
/* 0x005c        */     restore %i5,%lo(.L18),%o0       ! delay slot instr. restore the caller's window.
                                ! the subroutine return value is in %o0

            .L77000033:
/* 0x0060     20 */     sethi   %hi(.L21),%i2       ! set the high 22-bits of %i2 to the address of .L21
                                ! (string to be passed to printf)
/* 0x0064     16 */     mov     1,%i4           ! ** note that the instrs marked "**" are unnecessary. These instrs
                                ! perform the same function as those earlier in the program. They are created
                                ! by the compiler as it is not aware that ( exit(1) ) will terminate the
                                ! program.
/* 0x0068     20 */     add     %i2,%lo(.L21),%o0   ! add high and low bits 
!                                  to complete formation of address of .L21
/* 0x006c     15 */     mov     0,%i3           ! **
/* 0x0070     20 */     call    printf  ! params =  %o0 %o1 ! Call printf with args  %o0 and %o1
/* 0x0074        */     mov     %i0,%o1
/* 0x0078     21 */     call    exit    ! params =  %o0     ! Call exit whose 1st arg is %o0
/* 0x007c        */     mov     1,%o0           ! **
/* 0x0080        */     add     %i0,-1,%l5          ! **
/* 0x0084     24 */     mov     2,%l4           ! **
/* 0x0088        */     ba      .L900000109         ! **
/* 0x008c     15 */     sethi   %hi(.L18),%i1       ! **

/* 0x0090      0 */     .type   fibonacci,#function     ! set the type of fibonacci to be a function
/* 0x0090      0 */     .size   fibonacci,(.-fibonacci) ! set the size of the function
                                ! size of function:
                                !   current location counter minus beginning definition of function


            .L900000113:

    .section    ".text",#alloc,#execinstr
/* 000000      0 */     .align  4

!   31        !}
!   33        !int main()
!   34        !{

!
! SUBROUTINE main
!
! OFFSET    SOURCE LINE LABEL   INSTRUCTION

            .global main

            main:

            .L900000210:
/* 000000     34 */     save    %sp,-104,%sp
/* 0x0004      0 */     sethi   %hi(.L34),%i5
/* 0x0008      0 */     add     %i5,%lo(.L34),%i1

!   35        !  int n, i;
!   36        !  unsigned * result;
!   38        !  printf("Fibonacci(n):, please enter n:\n");

/* 0x000c     38 */     call    printf      ! params =  %o0
/* 0x0010        */     mov     %i1,%o0

!   39        !  scanf("%d", &n);

/* 0x0014     39 */     add     %i1,32,%o0      ! %o0 = %i1+32 (&.L35)
/* 0x0018        */     call    scanf       ! params =  %o0 %o1
/* 0x001c        */     add     %fp,-4,%o1      ! %o1 = %fp-4 (&n)

!   41        !  result = fibonacci(n);

/* 0x0020     41 */     call    fibonacci       ! params =  %o0 ! Result =  %o0. On return from the
                            ! routine, %o0 = &fib_array
/* 0x0024        */     ld      [%fp-4],%o0     ! delay slot instr. load the value at %fp-4 (n) into %o0
/* 0x0028        */     ld      [%fp-4],%i4     ! load the value at %fp-4 (n) into %i4

!   42        !  for (i = 1; i <= n; i++)

/* 0x002c     42 */     cmp     %i4,1       ! n < 1 ?
/* 0x0030        */     bl,pn   %icc,.L77000075 ! if yes, branch to end of main()
/* 0x0034     41 */     mov     %o0,%i2     ! %i2 (result) = %o0 ( result of fibonacci() )

!   43        !    printf("Fibonacci (%d) is %u\n", i, *result++);

            .L77000082:
/* 0x0038     42 */     mov     1,%i3       ! i = 1

            .L900000207:
                            ! beginning of loop body
/* 0x003c     43 */     ld      [%i2],%o2       ! %o2 (3rd arg) = value at &result
/* 0x0040        */     add     %i1,36,%o0      ! %o0 (1st arg) = %i1+36 (&.L40)
/* 0x0044        */     add     %i2,4,%i2       ! increment &result by 4, result now points to the
                            ! next value in fib_array[]
/* 0x0048        */     call    printf  ! params =  %o0 %o1 %o2 ! Result =
/* 0x004c        */     mov     %i3,%o1     ! %o1 (2nd arg) = %i3 (i)
/* 0x0050        */     ld      [%fp-4],%i0     ! %i0 = value at %fp-4 (n)
/* 0x0054     42 */     add     %i3,1,%i3       ! increment i by 1
/* 0x0058        */     cmp     %i3,%i0     ! i <= n ?
/* 0x005c        */     ble,pt  %icc,.L900000207! if yes, goto beginning of loop body
/* 0x0060        */     nop             ! end of the loop body

            .L77000075:
/* 0x0064     42 */     ret
/* 0x0068        */     restore %g0,0,%o0
/* 0x006c      0 */     .type   main,#function
/* 0x006c      0 */     .size   main,(.-main)