Assembly Program for Reading an Unsigned Integer

The “hello, world!” program will later be used for as a building block for a function printing string. But we will need more input/output functionality, e.g. reading and printing integers.

In this session we first implement an assembly program for reading an unsigned integer.

Instruction Set Used in the Video

RRR     (OP u 8) (X u 8) (Y u 8) (Z u 8)
J26     (OP u 8) (XYZ j 24)
U16R    (OP u 8) (XY u 16) (Z u 8)


0x01    RRR
:   halt    %X
    ulm_halt(ulm_regVal(X));

0x02    RRR
:   getc    %X
    ulm_setReg(ulm_readChar() & 0xFF, X);

0x03    RRR
:   putc    %X
    ulm_printChar(ulm_regVal(X) & 0xFF);

0x04    J26
:   jmp XYZ
    ulm_unconditionalRelJump(XYZ);

0x05    RRR
:   subq    X, %Y, %Z
    ulm_sub64(X, ulm_regVal(Y), Z);

0x06    J26
:   jnz XYZ
:   jne XYZ
    ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 0, XYZ);

0x07    J26
:   jz  XYZ
:   je  XYZ
    ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 1, XYZ);

0x08    U16R
:   ldzwq   XY, %Z
    ulm_setReg(XY, Z);

0x09    RRR
:   movzbq (%X), %Z
    ulm_fetch64(0, X, 0, 0, ULM_ZERO_EXT, 1, Z);

0x0A    RRR
:   addq    X, %Y, %Z
    ulm_add64(X, ulm_regVal(Y), Z);

0x0B    RRR
:   imulq   %X, %Y, %Z
    ulm_mul64(ulm_regVal(X), ulm_regVal(Y), Z);

0x0C    J26
:   ja      XYZ
    ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 0
                        && ulm_statusReg[ULM_CF] == 0, XYZ);

0x0D    J26
:   jb      XYZ
    ulm_conditionalRelJump(ulm_statusReg[ULM_CF] == 1, XYZ);

0x0E    RRR
:   addq    %X, %Y, %Z
    ulm_add64(ulm_regVal(X), ulm_regVal(Y), Z);

0x0F    RRR
:   imulq   X, %Y, %Z
    ulm_mul64(X, ulm_regVal(Y), Z);

The get_uint64.s Program Shown in the Video

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
    .equ    dest,   1
    .equ    ch,     2

    .text
    ldzwq   0,  %dest

read:
        getc    %ch
#   if %ch < '0' then we are done
    subq    '0',    %ch,    %0
    jb      done
#   if %ch > '9' then we are done
    subq    '9',    %ch,    %0
    ja      done

    subq    '0',    %ch,    %ch
    imulq   10,     %dest,  %dest
    addq    %ch,    %dest,  %dest
    jmp     read

done:
    halt    %dest

Translating the Assembly Program into an Executable

With

theon$ 1_ulm_build/io/ulmas 0_ulm_variants/io/get_uint64.s
theon$ 

the following exectuable a.out (the default name for the assembler output) gets created:

#TEXT 4
0x0000000000000000: 08 00 00 01 #     ldzwq 0, %dest
0x0000000000000004: 02 02 00 00 #     getc %ch
0x0000000000000008: 05 30 02 00 #     subq 48, %ch, %0
0x000000000000000C: 0D 00 00 07 #     jb done
0x0000000000000010: 05 39 02 00 #     subq 57, %ch, %0
0x0000000000000014: 0C 00 00 05 #     ja done
0x0000000000000018: 05 30 02 02 #     subq 48, %ch, %ch
0x000000000000001C: 0F 0A 01 01 #     imulq 10, %dest, %dest
0x0000000000000020: 0E 02 01 01 #     addq %ch, %dest, %dest
0x0000000000000024: 04 FF FF F8 #     jmp read
0x0000000000000028: 01 01 00 00 #     halt %dest
#DATA 1
#BSS 1 0
#SYMTAB
a dest                 0x0000000000000001
a ch                   0x0000000000000002
t read                 0x0000000000000004
t done                 0x0000000000000028

Some Test Run

Using file redirection we can also read an unsigned integer from a file like this:

So we can check the program like that:

theon$ 1_ulm_build/io/ulm a.out < test.txt
theon$ echo $?
123
theon$ 

Quiz 9

Write an assembler program that reads an unsigned integer, computes the factorial for this integer and then halts the program with the computed value as exit code.

Hand in your instruction set architecture isa.txt and your assembly program factorial.s with submit hpc quiz09 isa.txt get_uint_factorial.s.