assemblymarie

MARIE: How to print a name


I got a question that wants the user to input a first name and a last name and then print it out. The question also wants me to print out a space between the first and last name as well, which I am having trouble figuring out how to do that. I have also made it so that if the user inputs '$', the program will stop taking in inputs and move on to the printing subroutine. This is my code so far.

 /main program
 FirstNameLoop,     JnS SubInputFirstName
                    Load Name
                    Add One
                    Store Name
                    Jump FirstNameLoop

 LastNameLoop,      Jns SubInputLastName
                    Load Name
                    Add One
                    Store Name
                    Jump LastNameLoop


 /subroutine for inputting firstname
 SubInputFirstName, Hex 0
                    Input
                    Store Temp
                    Subt Comma
                    Skipcond 400
                    Jump StoreFirstName
                    Load Comma
                    Add One
                    StoreI Name
                    Jump LastNameLoop
 StoreFirstName,    Load Temp
                    StoreI Name
                    JumpI SubInputFirstName
                
 End,               JnS subPrintString
                    Load NamePrint
                    Add One
                    Store NamePrint
                    Jump End
 Finish,            Halt
                

 /subroutine for entering last name                    
 SubInputLastName,  HEX 0
                    Input 
                    Store Temp
                    Subt Dollar
                    Skipcond 400
                    Jump StoreLastName
                    Jump End

 StoreLastName,     Load Temp
                    StoreI Name
                    JumpI SubInputLastName


 /subroutine for printing name
 subPrintString,    HEX 0
                    LoadI NamePrint
                    Store Temp
                    Subt Period
                    Skipcond 400
                    Jump PrintName
                    Jump Finish
 PrintName,         Load Temp               
                    Output
                    JumpI subPrintString
                
 NamePrint, HEX 300       
 Dollar, Dec 36
 Name, HEX 300
 One, DEC 1
 Temp, DEC 0
 Space, DEC 32
 Comma, DEC 44
 Period, DEC 46

Solution

  • The computer can remember almost anything, but it has to be told exactly what to remember and when to do so, otherwise information that it is not programmed to remember can be lost with no way to recover it.

    Since you are storing the first name and the last name in the same data structure, once it starts to print, the program has no way to know where the first name ends and the last name begins — that information has been lost.  (In fact, that information is lost as soon as the initial character of the last name is requested.)

    There are many ways to capture & convey the information from where it exists to where it is needed.  First, we look to the point in the program where the information still exists — it is at the logical transition between entry of the first name and entry of the last name.  That is the only point in the program where we know something special (about first vs. last name).  When the program sees the , character it stops entry of the first name and transitions to entry of the last name.  (We can think of programs as state machines, and, their piece parts as states: here the program is logically transitioning from the first name input state to the last name input state.)

    As part of the logical transition from entering first name to entering last name, you can

    (a) capture the current name pointer, as it points to the first character of the last name (which has not yet been captured).  Having captured this at this transition, later the printing code can ask and answer the question of: is this the first character of the last name, and if so, then insert a space into the output.

    (b) put a counter in the first name loop (but not in the second name loop).  The counter will stop incrementing when the first name loop is finished, so it will hold at the length of the first name.  Later, the printing code can ask and answer the question of have we printed as many characters as were in the first name, so as to insert a space into the output after the first name's final character.

    (c) enter a space directly into the name string data structure at that transition from first name entry to last name entry, so that the print output will print a space between them without really knowing anything special about first name and last name.

    (d) store the first name and last name in a different data structure (two separate strings).  Print the first string, then print a space, then print the second string.


    Similarly, as part of transitioning from accepting last name to printing, you should append a . character to the string so that print routine knows where to stop.  Otherwise, you might look for 0 (nul) character instead of a . for output print termination.


    You are using subroutines, but also jumping from the subroutine back to the main directly when encountering a transition rather than "returning" — while this is working, it is very bad form because it is unstructured control flow.  This kind of control flow is why Dijkstra published as "Go To Statement Considered Harmful" in 1968.

    There is no way to write that control flow in structured pseudo code or in C — in any modern programming language we cannot jump directly from a subroutine/function to anywhere in another subroutine/function, like main.  The only thing a function can do is return to its caller.  This way, a function can be used from any other function in the same program, even from multiple places in some other function, or from multiple other functions.  A function, once written, can be used in another program, too.

    There are a number of possible solutions, one of which is that, the subroutine would returns an answer, which tells the caller whether or not a transition has occurred.  The caller then uses the answer to decide whether to stay in the loop or transition to the next part of main.

    Another solution is to move more functionality into the subroutine, for example, to enter the entire first name.  The looping and incrementing would be inside the subroutine, and thus, it would only return to caller when the entire first name has been entered.  The main would simply call one subroutine, then the other (the looping having been moved into the subroutines).


    The 2nd subroutine is virtually a duplicate of the first one, with only one difference, the character to use for transition.  By abstracting the notion of the transition character — pass the , or $ as a parameter — the same subroutine could be used for both first name and last name entry.