|
| 1 | +;------------------------------------------ |
| 2 | +; int atoi(Integer number) |
| 3 | +; Ascii to integer function (atoi) |
| 4 | +atoi: |
| 5 | + push ebx ; preserve ebx on the stack to be restored after function runs |
| 6 | + push ecx ; preserve ecx on the stack to be restored after function runs |
| 7 | + push edx ; preserve edx on the stack to be restored after function runs |
| 8 | + push esi ; preserve esi on the stack to be restored after function runs |
| 9 | + mov esi, eax ; move pointer in eax into esi (our number to convert) |
| 10 | + mov eax, 0 ; initialise eax with decimal value 0 |
| 11 | + mov ecx, 0 ; initialise ecx with decimal value 0 |
| 12 | + |
| 13 | +.multiplyLoop: |
| 14 | + xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 |
| 15 | + mov bl, [esi+ecx] ; move a single byte into ebx register's lower half |
| 16 | + cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) |
| 17 | + jl .finished ; jump if less than to label finished |
| 18 | + cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) |
| 19 | + jg .finished ; jump if greater than to label finished |
| 20 | + cmp bl, 10 ; compare ebx register's lower half value against ascii value 10 (linefeed character) |
| 21 | + je .finished ; jump if equal to label finished |
| 22 | + cmp bl, 0 ; compare ebx register's lower half value against decimal value 0 (end of string) |
| 23 | + jz .finished ; jump if zero to label finished |
| 24 | + |
| 25 | + sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value |
| 26 | + add eax, ebx ; add ebx to our interger value in eax |
| 27 | + mov ebx, 10 ; move decimal value 10 into ebx |
| 28 | + mul ebx ; multiply eax by ebx to get place value |
| 29 | + inc ecx ; increment ecx (our counter register) |
| 30 | + jmp .multiplyLoop ; continue multiply loop |
| 31 | + |
| 32 | +.finished: |
| 33 | + mov ebx, 10 ; move decimal value 10 into ebx |
| 34 | + div ebx ; divide eax by value in ebx (in this case 10) |
| 35 | + pop esi ; restore esi from the value we pushed onto the stack at the start |
| 36 | + pop edx ; restore edx from the value we pushed onto the stack at the start |
| 37 | + pop ecx ; restore ecx from the value we pushed onto the stack at the start |
| 38 | + pop ebx ; restore ebx from the value we pushed onto the stack at the start |
| 39 | + ret |
| 40 | + |
| 41 | + |
| 42 | +;------------------------------------------ |
| 43 | +; void iprint(Integer number) |
| 44 | +; Integer printing function (itoa) |
| 45 | +iprint: |
| 46 | + push eax ; preserve eax on the stack to be restored after function runs |
| 47 | + push ecx ; preserve ecx on the stack to be restored after function runs |
| 48 | + push edx ; preserve edx on the stack to be restored after function runs |
| 49 | + push esi ; preserve esi on the stack to be restored after function runs |
| 50 | + mov ecx, 0 ; counter of how many bytes we need to print in the end |
| 51 | + |
| 52 | +.divideLoop: |
| 53 | + inc ecx ; count each byte to print - number of characters |
| 54 | + mov edx, 0 ; empty edx |
| 55 | + mov esi, 10 ; mov 10 into esi |
| 56 | + idiv esi ; divide eax by esi |
| 57 | + add edx, 48 ; convert edx to it's ascii representation - edx holds the remainder after a divide instruction |
| 58 | + push edx ; push edx (string representation of an intger) onto the stack |
| 59 | + cmp eax, 0 ; can the integer be divided anymore? |
| 60 | + jnz .divideLoop ; jump if not zero to the label divideLoop |
| 61 | + |
| 62 | +.printLoop: |
| 63 | + dec ecx ; count down each byte that we put on the stack |
| 64 | + mov eax, esp ; mov the stack pointer into eax for printing |
| 65 | + call sprint ; call our string print function |
| 66 | + pop eax ; remove last character from the stack to move esp forward |
| 67 | + cmp ecx, 0 ; have we printed all bytes we pushed onto the stack? |
| 68 | + jnz .printLoop ; jump is not zero to the label printLoop |
| 69 | + |
| 70 | + pop esi ; restore esi from the value we pushed onto the stack at the start |
| 71 | + pop edx ; restore edx from the value we pushed onto the stack at the start |
| 72 | + pop ecx ; restore ecx from the value we pushed onto the stack at the start |
| 73 | + pop eax ; restore eax from the value we pushed onto the stack at the start |
| 74 | + ret |
| 75 | + |
| 76 | + |
| 77 | +;------------------------------------------ |
| 78 | +; void iprintLF(Integer number) |
| 79 | +; Integer printing function with linefeed (itoa) |
| 80 | +iprintLF: |
| 81 | + call iprint ; call our integer printing function |
| 82 | + |
| 83 | + push eax ; push eax onto the stack to preserve it while we use the eax register in this function |
| 84 | + mov eax, 0Ah ; move 0Ah into eax - 0Ah is the ascii character for a linefeed |
| 85 | + push eax ; push the linefeed onto the stack so we can get the address |
| 86 | + mov eax, esp ; move the address of the current stack pointer into eax for sprint |
| 87 | + call sprint ; call our sprint function |
| 88 | + pop eax ; remove our linefeed character from the stack |
| 89 | + pop eax ; restore the original value of eax before our function was called |
| 90 | + ret |
| 91 | + |
| 92 | + |
| 93 | +;------------------------------------------ |
| 94 | +; int slen(String message) |
| 95 | +; String length calculation function |
| 96 | +slen: |
| 97 | + push ebx |
| 98 | + mov ebx, eax |
| 99 | + |
| 100 | +.nextchar: |
| 101 | + cmp byte [eax], 0 |
| 102 | + jz .finished |
| 103 | + inc eax |
| 104 | + jmp .nextchar |
| 105 | + |
| 106 | +.finished: |
| 107 | + sub eax, ebx |
| 108 | + pop ebx |
| 109 | + ret |
| 110 | + |
| 111 | + |
| 112 | +;------------------------------------------ |
| 113 | +; void sprint(String message) |
| 114 | +; String printing function |
| 115 | +sprint: |
| 116 | + push edx |
| 117 | + push ecx |
| 118 | + push ebx |
| 119 | + push eax |
| 120 | + call slen |
| 121 | + |
| 122 | + mov edx, eax |
| 123 | + pop eax |
| 124 | + |
| 125 | + mov ecx, eax |
| 126 | + mov ebx, 1 |
| 127 | + mov eax, 4 |
| 128 | + int 80h |
| 129 | + |
| 130 | + pop ebx |
| 131 | + pop ecx |
| 132 | + pop edx |
| 133 | + ret |
| 134 | + |
| 135 | + |
| 136 | +;------------------------------------------ |
| 137 | +; void sprintLF(String message) |
| 138 | +; String printing with line feed function |
| 139 | +sprintLF: |
| 140 | + call sprint |
| 141 | + |
| 142 | + push eax |
| 143 | + mov eax, 0AH |
| 144 | + push eax |
| 145 | + mov eax, esp |
| 146 | + call sprint |
| 147 | + pop eax |
| 148 | + pop eax |
| 149 | + ret |
| 150 | + |
| 151 | + |
| 152 | +;------------------------------------------ |
| 153 | +; void exit() |
| 154 | +; Exit program and restore resources |
| 155 | +quit: |
| 156 | + mov ebx, 0 |
| 157 | + mov eax, 1 |
| 158 | + int 80h |
| 159 | + ret |
| 160 | + |
0 commit comments