25

Hello World…Not so easy in Assembly

 4 years ago
source link: https://www.tuicool.com/articles/eQN3M3A
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Hello World…Not so easy in Assembly

Introduction

In this blog post I will walk through a Hello World program in assembly (RISC style Nios II architecture). Although I will not go into detail about what Nios II architecture means, it is important to mention that in order to run the Hello World program, either a computer board or simulator that supports Nios II architecture is required. I recommend using the simulator found here .

Hello World in Other Languages

Hello World is often the first program new programmers write as it is very simple. I will demonstrate the Hello World program in C, Ruby, JavaScript, and Java to emphasize the simplicity of this program.

Hello World in C

aIRFRbz.png!web
Figure 1: Hello World in C

Hello World in Ruby

Figure 2: Hello World in Ruby

Hello World in JavaScript

Figure 3: Hello World in JavaScript

Hello World in Java

uUZzUjR.png!web

Figure 4: Hello World in Java

Hello World in Assembly

Before I unveil the assembly version of Hello World, I must give you a warning that it is quite long and scary, but I will explain everything to the best of my abilities after. Without further ado, the moment we have all been waiting for, Hello World in assembly:

3UFB7vB.png!web

Yes, I know, it looks very scary. Hopefully, you have not clicked off the blog yet. In Figure 5, lines 1–5 are initializing constants. For example, the first line sets LAST_RAM_WORD to 0x007FFFFC which is a memory location in hexadecimal. Line 8 allows the linker to know where the program starts. In this case, the program starts on line 11. Line 9 lets the assembler know that the memory location of the following line. In Figure 5, line 9 tells the assembler that _start: is at location 0x00000000.

Now, I will explain what is happening in the _start: label, beginning on line 11 in Figure 5. The first line inside of _start:, line 12, moves the value of LAST_RAM_WORD to the stack pointer (sp). That line has essentially initiated sp to contain memory address, 0x007FFFFC. The following line moves ‘\n’ or the next line character into register 2, an internal register on the CPU. Line 14 calls PrintChar. This means that the program will begin executing the code following the PrintChar: label starting on line 20. For simplicity, from now on I will refer to _start:, _end:, PrintChar:, and PrintString: as functions or routines even though they are labels.

The PrintChar: function is in charge of printing a character to the screen. To clarify, this program actually prints the new line character followed by the hello world string. The reason I chose to insert the new line character was to explain the PrintChar: function before explaining the PrintString: function which just calls the PrintChar: function multiple times. To explain this function, I will define word addressable memory. A word can be thought of as a memory unit which can store information. In Nios II architecture, a word is 4 bytes or 32 bits. This PrintChar: function begins by subtracting eight bytes from sp, essentially generating space for two words. Lines 22 and 23 store the current values of registers three and four into the generated spaces. This is important because the CPU contains a limited number of registers that can be used, so storing the value of these registers allows the function to use the registers and restore their values when the function is finished. Line 24 sets the value of register three to 0x10001000, which is the input/output location. Line 25 is a label (pc_loop:). The relevance of this label will become apparent in a moment after defining the next three lines. Line 26 loads the status of the input/output location into register four. Line 27 logically ands the upper bits of the value in register four and WSPACE_MASK (0xFFFF) and then stores the result in register four. The “beq” in line 28 stands for “branch equal to.” Essentially, line 28 causes the program to loop back to the “pc_loop” label (line 25) if the value of register four equals the value of register zero. To clarify, register zero is a special register that always has a value of zero. Lines 25 through 28 represent a while loop from a higher level language. The while loop causes the program to wait until the output device is ready to print the character. Line 29 outputs the contents of register two to the console. In other words, line 29 is the line responsible for making the letter appear on the screen. Line 30 and 31 restore the values of register three and four to their values before entering the PrintChar: function. After the values are restored, the stack pointer (sp) no longer needs to store data, thus line 32 adds 8 bytes to the stack pointer to return sp to its original state. Finally, the program returns to the line following the call to PrintChar or line 15 upon hitting “ret” on line 33.

Once we return to line 15, register two is given the address of the string we are trying to print, “Hello World\n”. Then, on line 16, the PrintString: method is called. To keep it concise, this method loops through the string, sending each letter to the PrintChar: method. So initially, the “H” in “Hello World\n” is sent to the PrintChar: method. Then, the “e” is sent to the PrintChar: method. This process (loop) will continue until the “\n” character.

Upon termination of the PrintString: routine, the program returns to line 17, or the _end: label. Then, on line 18, the program branches back to line 17 an infinite number of times which essentially cause the program to terminate as it is stuck in an infinite loop.

For anyone wondering, lines 54 and 55 let the program know that the “Hello World\n” string begins in memory location 0x1000.

Conclusion

Assembly is a very interesting language that is a lot harder to learn as it requires knowledge of the hardware you are working with. As previously mentioned, this assembly program was written in RISC style Nios II architecture (a version of assembly). The Hello World program is a lot harder in assembly than any high level programming language as it requires the programmer to define the program entirely such as specifying memory locations. Furthermore, in assembly, the programmer must specify what appears on the screen and when, which is why the program loops through the string and prints one character at a time. However, assembly allows programmers to optimize programs and algorithms by taking advantage of hardware features which may not be possible otherwise.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK