Say “hello, world!” with assembly

Assembly notation is equivalent to machine code. But more expressive. Here we mainly focus on “seeing” the equivalence. This means every assembly instruction represents exactly one machine instruction. And vice versa, every machine instruction can be represented by one assembly instruction. Expressing machine code with assembly code will be explained in the video. In the assignment you have to do it the way around, i.e. translate machine code instructions into assembly notation.

For now, more expressive means that you can write instructions in some symbolic form (e.g. using mnemonics like addq), and that we can use decimal, octal or hexadecimal notations for numerals. In upcoming session you will see that assembly code can provide you much more convenience.

Video tutorial

This video explains the assembly notation described in the Instruction Set of the ULM.

Here the “hello, world!” program in assembly as shown in the video:

1
2
3
4
5
6
7
8
9
    ldzwq       32,     %1
    movzbq      0(%1),  %2
    subq        0,      %2,     %0
    jz          16
    putc        %2
    addq        1,      %1,     %1
    jmp         -20
    halt        0
    .string     "hello, world!\n"

Using the -o you can specify the name of the output file (default would be a.out):

theon$ ulmas -o hello hello.s
theon$ 

Here the generated machine code:

theon$ cat hello
#TEXT 4
0x0000000000000000: 56 00 20 01 #       ldzwq 32, %1
0x0000000000000004: 1B 00 01 02 #       movzbq 0(%1), %2
0x0000000000000008: 39 00 02 00 #       subq 0, %2, %0
0x000000000000000C: 42 00 00 04 #       jz 16
0x0000000000000010: 61 02 00 00 #       putc %2
0x0000000000000014: 38 01 01 01 #       addq 1, %1, %1
0x0000000000000018: 41 FF FF FB #       jmp -20
0x000000000000001C: 09 00 00 00 #       halt 0
0x0000000000000020: 68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 0A 00 #      .string "hello, world!\n"
theon$ 

And here we run it on the ULM:

theon$ ulm hello
hello, world!
theon$ 

Exercise: What's it doing?

What is the following program doing? Can you express that with some flow chart?

1
2
3
4
5
6
7
        jmp     12
        addq    1,      %1,     %1
        putc    %1
        getc    %1
        subq    0x0A,   %1,     %0
        jnz     -16
        halt    1

Of course you should test it. Translate it with the ulm assembler

theon$ ulmas foo.s
theon$ 

and then run it on ulm or ulm-qui.

Teaser for learning more about labels

From this the assembler will generate the same code:

1
2
3
4
5
6
7
        jmp     check
do      addq    1,      %1,     %1
        putc    %1
        getc    %1
check   subq    0x0A,   %1,     %0
        jnz     do
        halt    1

Exercise: Disassembler

Sorry, we don't have a disassembler for the ULM. So you have to do it! Express the following machine code in assembly:

1
2
3
4
5
34 01 02 03
3C 2A 02 03
33 03 02 04
20 01 02 04
28 01 02 04