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.