0

I use MMIX from this site: http://mmix.cs.hm.edu/ I used this code to get the console to print "Hello World" "times" times:

times IS 3

msg BYTE "Hello World",#A,0
Main GETA $255,msg
    SET $91,times
    MUL $91,$91,2
    SUB $91,$91,1 
    TRAP 0,Fputs,StdOut
    BP $91,@-8
    TRAP 0,Halt,0

I was wondering why this only produces 3 of them. Looking at the code, because I multiplied times by 3, it should print Hello World 3 times. However upon closer inspection I noticed "00000701 (TRAP) $255 = Fputs(StdOut,#c) = 0" AND "00000701 (TRAP) $255 = Fputs(StdOut,#0) = 12" would alternate. I assumed this is the cause. But why does this happen?

I'm very new to coding in this language, so please take it easy on the terminology.

  • can you find trap 0 docs? (too lazy to search for it)... one would expect it to return number of characters outputted, so alternating 0/12 value makes that mul by 2 logical, but why it does output 0 bytes every other time is weird. (and is this, what you are asking?) – Ped7g Mar 04 '18 at 09:27
  • Yes that is.what I'm looking for. – Sancho Jimenez Mar 04 '18 at 13:59
  • Does the `$255` register keeps it value after trap `Fputs`? Maybe you should set it up to `msg` address ahead of every `trap` call. But then why would it work every second time ... no idea. Sorry, I'm not willing to study how exactly this assembly variant works, seems way too different from CPUs I already know, so this is basically all I had. – Ped7g Mar 04 '18 at 15:54
  • Did you try single-stepping through the code in a debugger, and watching register values? I assume there's an MMIX simulator with a debugger. – Peter Cordes Mar 06 '18 at 05:51

1 Answers1

2

This is an interesting bug. Indeed the output is:

Hello World
Hello World
Hello World

Why it does so is a consequence of the way this toy program is assembled and the way output works in MMIX

When the program is assembled in memory, it starts out with the string at address 0x0 - the bytes are:

0  1  2  3  4  5  6  7  8  9  10  11  12  ...
H  e  l  l  o  _  W  o  r  l   d  \n  \0  ...

The output instruction is

    TRAP 0,Fputs,StdOut

This instruction prints the string whose address is in register $255 and places a return value in $255. The return value is the number of bytes written on success and -1 on error

The loop does run 6 times as intended but what happens is this:

The loop begins with $255 set to 0 which is the address of the string

The first iteration prints "Hello World\n" and sets $255 to 12 which is the length of the string

The second time $255 has the value 12 - this is used as the address of the string to print. You can see in the memory layout above, address 12 has a NUL character. This makes the TRAP print nothing with success and $255 is set to 0 for number of bytes written.

The third time $255 has the value 0 which is the valid address of the string so it gets printed and $255 is set to 12 for the length of the string written.

You get the idea.

So the string is printed every other time for a total of 3 times out of 6

The fix is to set $255 to the address of the string inside the loop. The complete program is:

times IS 3

msg   BYTE "Hello World",#A,0
Main  SET $91,times
      MUL $91,$91,2
      SUB $91,$91,1 
      GETA $255,msg
      TRAP 0,Fputs,StdOut
      BP $91,@-12
      TRAP 0,Halt,0
Zartaj Majeed
  • 500
  • 2
  • 8