1

I have an assignment where I have to take an input in MMIX and return the exact same thing, with the exception that all spaces must be newlines. I've been trying for about 2 days now and have figured out how to take input and how to output it to the console. But the second part eludes me and the assignment is due tomorrow. Here's what I have so far:

    LOC Data_Segment         % Sets data storage location
    GREG    @                % Reserves a new global register
Wordbuffer  BYTE    0        % New Byte for incoming words

    LOC     Wordbuffer+5     % After the buffer
Arg OCTA    Wordbuffer      
    OCTA    21               % Sets max word length
    LOC    #100              % Code section

Main    LDA    $255,Arg   % Loads the buffer into the global register
    TRAP    0,Fgets,StdIn    % Gets input
    LDA     $255,Wordbuffer  % Puts input in global register
    TRAP    0,Fputs,StdOut   % Prints inputted word
    TRAP    0,Halt,0         % Stops program
  • So, what exactly is unclear to you? What have you tried? – fuz Mar 20 '18 at 14:01
  • This seems weird. You only reserve 5 bytes for `Wordbuffer` before `Arg` ([which has the pointer + length for `fgets`](http://mmix.cs.hm.edu/doc/mmix-refcard-a4.pdf)). If you're going to let `fgets` overwrite the `Arg` buffer, you might as well put it at the start of `Wordbuffer`. (`Fputs` takes a pointer to a null-terminated string rather than a control block, so you can overwrite it if you only want to call `Fgets` once). And you use an absolute `LOC` for your code, but let the assembler choose where `Data_Segment` goes? – Peter Cordes Mar 20 '18 at 14:25
  • Does `Fgets` return a length? You could loop backwards from the end of the string, counting down that length, or loop forwards counting another counter up to that length, loading a byte and conditionally storing a newline if the byte is a `' '`. Then call `Fputs` as normal. – Peter Cordes Mar 20 '18 at 14:28
  • 1) Whoops that was suppost to be a 21, forgot to change that back. 2) I have no idea what I'm doing. Nothing was actually taught to us, we were told to "figure it out". 3) How would I go about acessing the memory location at which the String is saved? And how could I loop through it? Thanks in advance, sorry for the late reply, I was trying to go through a book I found that ended up not helping. Or possibly could you give me a link or something that I could look at that might help? – Sancho Jimenez Mar 20 '18 at 14:56
  • @fuz I've tried multiple things. but they make no sense, and as such also don't work so I didn't mention them here. I tried to save the String into a variable and check if it equals ' ' but that doesn't make sense. I currently have no method of checking each individual character in a string... I wish there were more sources of information online. – Sancho Jimenez Mar 20 '18 at 15:02
  • @SanchoJimenez To compare an individual character, load one character from the buffer into a register using `LDBU` and then compare that character. – fuz Mar 20 '18 at 15:05
  • @SanchoJimenez: get the address into a register and use `ldbu`. Increment the register holding the pointer to make it point to the next character. Look at a MMIX instruction-set reference. – Peter Cordes Mar 20 '18 at 22:20

1 Answers1

3

I've inserted a loop between the calls to Fgets and Fputs

Also responding to comments

  • Data_Segment is a fixed address - where writable data starts in MMIX memory
  • Fgets returns the number of bytes read or -1 - the string is null-terminated
  • LOC #100 (0x100) is typically where the main program starts - special interrupt handlers can be placed in lower addresses
// space_to_newline.mms
              LOC     Data_Segment     % Sets data storage location
              GREG    @                % Reserves a new global register
Wordbuffer    BYTE    0                % New Byte for incoming words
              LOC     Wordbuffer+5     % After the buffer
Arg           OCTA    Wordbuffer
              OCTA    21               % Sets max word length
              LOC     #100             % Code section

Main          LDA     $255,Arg         % Loads the buffer into the global register
              TRAP    0,Fgets,StdIn    % Gets input
// loop over the string in Wordbuffer
// check if each character is a space
// replace with newline (0xa) if so
nl            GREG    #0a              newline constant
              LDA     $0,Wordbuffer    load base address
              SET     $1,0             initialize index to zero

0H            LDBU    $2,$0,$1         load byte in $2
              BZ      $2,2F            done if null byte
              CMP     $255,$2,' '      check if space
              PBNZ    $255,1F          skip character if not space
              STBU    nl,$0,$1         fallthru to replace with newline
1H            INCL    $1,1             increment index
              JMP     0B               loop back
2H            LDA     $255,Wordbuffer  % Puts input in global register
              TRAP    0,Fputs,StdOut   % Prints inputted word
              TRAP    0,Halt,0         % Stops program

test with mmix assembler and simulator

$ mmixal space_to_newline.mms
$ echo "abc defgh ijklm nopq" | mmix space_to_newline
abc
defgh
ijklm
nopq
Zartaj Majeed
  • 500
  • 2
  • 8
  • How are the jumps here working? I had the impression that instructions in MMIX were 4 bytes long and that jumps jumped forward $arg / 4 insturctions. But your jumps look to be set to 47 (2f), 31 (1f) and 11 (0b); none of these evenly divide by 4. I thought maybe you could do something by counting instructions from Main, but that doesn't work for 0B. What's going on? – Fluffy Ribbit Jun 22 '23 at 06:32
  • The 2F in "BZ $2, 2F" is not hex - it's a Forward reference to the local label 2H below the instruction. Similarly 0B in "JMP 0B" is a Backward reference to the label 0H above the instruction. The "H" in local labels means Here. – Zartaj Majeed Jun 22 '23 at 11:57
  • How does MMIX know to go to 2h given 2f? Eventually I implemented this by just changing the jumps to match the labels: https://pasteboard.co/K66LVIR6wfZw.png – Fluffy Ribbit Jun 22 '23 at 21:27
  • That's the job of mmixal, the MMIX assembler - it generates machine code from assembly source – Zartaj Majeed Jun 23 '23 at 03:30