|
| 1 | += Chapter 1: Data |
| 2 | + |
| 3 | +In MIPS, you can declare global variables in the `.data` section. |
| 4 | + |
| 5 | +At a minimum this is where you would declare/define any literal strings |
| 6 | +your program will be printing, since virtually every program has |
| 7 | +at least 1 or 2 of those. |
| 8 | + |
| 9 | +When declaring something in the `.data` section, the format is |
| 10 | + |
| 11 | +`variable_name: .directive value(s)` |
| 12 | + |
| 13 | +where whitespace between the 3 is arbitrary. The possible directives are listed |
| 14 | +in the following table: |
| 15 | + |
| 16 | +.MIPS data types |
| 17 | +[cols="1,1,2"] |
| 18 | +|=== |
| 19 | +| Directive | Size | C equivalent |
| 20 | + |
| 21 | +| .byte | 1 | char |
| 22 | + |
| 23 | +| .half | 2 | short |
| 24 | + |
| 25 | +| .word | 4 | int |
| 26 | + |
| 27 | +| .float | 4 | float |
| 28 | + |
| 29 | +| .double | 8 | double |
| 30 | + |
| 31 | +| .ascii | NA | char str[5] = "hello"; (no '\0') |
| 32 | + |
| 33 | +| .asciiz | NA | char str[] = "hello"; (includes the '\0') |
| 34 | + |
| 35 | +| .space | NA | typeless, unitinialized space, can be used for any type/array |
| 36 | +|=== |
| 37 | + |
| 38 | + |
| 39 | +As you can see it's pretty straightforward, but there are a few more details |
| 40 | +about actually using them so let's move onto some examples. |
| 41 | + |
| 42 | +Say you wanted to convert the following simple program to MIPS: |
| 43 | + |
| 44 | +[source,c] |
| 45 | +---- |
| 46 | +#include <stdio.h> |
| 47 | +
|
| 48 | +int main() |
| 49 | +{ |
| 50 | + char name[30]; |
| 51 | + int age; |
| 52 | + printf("What's your name and age?\n"); |
| 53 | + scanf("%s %d", name, &age); |
| 54 | + printf("Hello %s, nice to meet you!\n", name); |
| 55 | + return 0; |
| 56 | +} |
| 57 | +---- |
| 58 | + |
| 59 | +The first thing you have to remember is that when converting from a higher level |
| 60 | +language to assembly (any assembly) is that what matters is whether it's functionally |
| 61 | +the same, not that everything is done in exactly the same way. In this instance, |
| 62 | +that means realizing that your literal strings and the name array become globals in |
| 63 | +MIPS. |
| 64 | + |
| 65 | +[source,mips] |
| 66 | +---- |
| 67 | +.data |
| 68 | +age: .word 0 # can be initialized to anything |
| 69 | +
|
| 70 | +ask_name: .asciiz "What's your name and age?\n" |
| 71 | +hello_space: .asciiz "Hello " |
| 72 | +nice_meet: .asciiz ", nice to meet you!\n" |
| 73 | +
|
| 74 | +name: .space 30 |
| 75 | +
|
| 76 | +.text |
| 77 | +
|
| 78 | +# main goes here |
| 79 | +
|
| 80 | +---- |
| 81 | + |
| 82 | +As you can see in the example, we just extract all the string literals and |
| 83 | +the character array name and declare them as MIPS globals. One thing to note |
| 84 | +is the second printf. Because it prints a variable, name, using the conversion |
| 85 | +specifier, we break the literal into pieces around that. Since there is no |
| 86 | +built-in printf function in MIPS, you have to handle printing variables yourself |
| 87 | +with the appropriate system calls. |
| 88 | + |
| 89 | + |
| 90 | +== Arrays |
| 91 | + |
| 92 | +Declaring arrays is just an extension of declaring single variables. Obviously |
| 93 | +strings are special cases, that can be handled with `.ascii` or `.asciiz` for literals, |
| 94 | +but for other types or user inputed strings how do we do it? |
| 95 | + |
| 96 | +Well the first way, which was demonstrated in the snippet above is to use `.space` |
| 97 | +to just declare array of the necessary byte size. Keep in mind that the size is |
| 98 | +specified in bytes not elements, so it only matches for character arrays. For |
| 99 | +arrays of ints/words, floats, doubles etc. you'd have to multiply by the sizeof(type). |
| 100 | + |
| 101 | +"But, `.space` only lets you declare uninitialized arrays, how do I do initialized ones?" |
| 102 | + |
| 103 | +Well, it's just an extension of declaring a single variable of that type. You specify |
| 104 | +all the values, comma separated. This actually gives you another way to declare a string |
| 105 | +or a character array, though I can't really think of a reason you'd want to. You could |
| 106 | +declare a `.byte` array and list all the characters individually. See below for examples. |
| 107 | + |
| 108 | +[source,c] |
| 109 | +---- |
| 110 | +int a[20]; |
| 111 | +double b[20]; |
| 112 | +int c[10] = { 9,8,7,6,5,4,3,2,1,0 }; |
| 113 | +char d[3] = { 'a', 'b', 'c' } |
| 114 | +---- |
| 115 | + |
| 116 | +becomes |
| 117 | + |
| 118 | +[source,mips] |
| 119 | +---- |
| 120 | +.data |
| 121 | +a: .space 80 |
| 122 | +b: .space 160 |
| 123 | +c: .word 9,8,7,6,5,4,3,2,1,0 |
| 124 | +d: .byte 'a', 'b', 'c' |
| 125 | +---- |
| 126 | + |
| 127 | + |
| 128 | + |
0 commit comments