|
67 | 67 | <li><a href="#lesson13">Lesson 13 <span>Calculator - subtraction</span></a></li> |
68 | 68 | <li><a href="#lesson14">Lesson 14 <span>Calculator - multiplication</span></a></li> |
69 | 69 | <li><a href="#lesson15">Lesson 15 <span>Calculator - division</span></a></li> |
| 70 | + <li><a href="#lesson16">Lesson 16 <span>Calculator (atoi)</span></a></li> |
70 | 71 | </ul> |
71 | 72 | </div> |
72 | 73 | </div> |
@@ -184,6 +185,15 @@ <h5>Calculator - division</h5> |
184 | 185 | </div> |
185 | 186 | </div> |
186 | 187 |
|
| 188 | + <div class="row-fluid"> |
| 189 | + <div class="span4"> |
| 190 | + <h2>Lesson 16</h2> |
| 191 | + <h5>Calculator (atoi)</h5> |
| 192 | + <p>This program takes a series of passed string arguments, converts them to integers and adds them all together.</p> |
| 193 | + <p><a class="btn" href="#lesson16">View lesson »</a></p> |
| 194 | + </div> |
| 195 | + </div> |
| 196 | + |
187 | 197 | <hr> |
188 | 198 |
|
189 | 199 | <div class="row-fluid" id="lesson1"> |
@@ -1468,6 +1478,105 @@ <h4>Calculator - division</h4> |
1468 | 1478 | </article> |
1469 | 1479 | </div> |
1470 | 1480 |
|
| 1481 | + <hr> |
| 1482 | + |
| 1483 | + <div class="row-fluid" id="lesson16"> |
| 1484 | + <article class="span12"> |
| 1485 | + <header> |
| 1486 | + <h2>Lesson 16</h2> |
| 1487 | + <h4>Calculator (atoi)</h4> |
| 1488 | + </header> |
| 1489 | + |
| 1490 | + <div class="snippet"> |
| 1491 | + <span class="filename">functions.asm</span> |
| 1492 | + <pre class="brush: asm;"> |
| 1493 | + ;------------------------------------------ |
| 1494 | + ; int atoi(Integer number) |
| 1495 | + ; Ascii to integer function (atoi) |
| 1496 | + atoi: |
| 1497 | + push ebx ; preserve ebx on the stack to be restored after function runs |
| 1498 | + push ecx ; preserve ecx on the stack to be restored after function runs |
| 1499 | + push edx ; preserve edx on the stack to be restored after function runs |
| 1500 | + push esi ; preserve esi on the stack to be restored after function runs |
| 1501 | + mov esi, eax ; move pointer in eax into esi (our number to convert) |
| 1502 | + mov eax, 0 ; initialise eax with decimal value 0 |
| 1503 | + mov ecx, 0 ; initialise ecx with decimal value 0 |
| 1504 | + |
| 1505 | + .multiplyLoop: |
| 1506 | + xor ebx, ebx ; resets both lower and uppper bytes of ebx to be 0 |
| 1507 | + mov bl, [esi+ecx] ; move a single byte into ebx register's lower half |
| 1508 | + cmp bl, 48 ; compare ebx register's lower half value against ascii value 48 (char value 0) |
| 1509 | + jl .finished ; jump if less than to label finished |
| 1510 | + cmp bl, 57 ; compare ebx register's lower half value against ascii value 57 (char value 9) |
| 1511 | + jg .finished ; jump if greater than to label finished |
| 1512 | + cmp bl, 10 ; compare ebx register's lower half value against ascii value 10 (linefeed character) |
| 1513 | + je .finished ; jump if equal to label finished |
| 1514 | + cmp bl, 0 ; compare ebx register's lower half value against decimal value 0 (end of string) |
| 1515 | + jz .finished ; jump if zero to label finished |
| 1516 | + |
| 1517 | + sub bl, 48 ; convert ebx register's lower half to decimal representation of ascii value |
| 1518 | + add eax, ebx ; add ebx to our interger value in eax |
| 1519 | + mov ebx, 10 ; move decimal value 10 into ebx |
| 1520 | + mul ebx ; multiply eax by ebx to get place value |
| 1521 | + inc ecx ; increment ecx (our counter register) |
| 1522 | + jmp .multiplyLoop ; continue multiply loop |
| 1523 | + |
| 1524 | + .finished: |
| 1525 | + mov ebx, 10 ; move decimal value 10 into ebx |
| 1526 | + div ebx ; divide eax by value in ebx (in this case 10) |
| 1527 | + pop esi ; restore esi from the value we pushed onto the stack at the start |
| 1528 | + pop edx ; restore edx from the value we pushed onto the stack at the start |
| 1529 | + pop ecx ; restore ecx from the value we pushed onto the stack at the start |
| 1530 | + pop ebx ; restore ebx from the value we pushed onto the stack at the start |
| 1531 | + ret |
| 1532 | + </pre> |
| 1533 | + </div> |
| 1534 | + |
| 1535 | + <div class="snippet"> |
| 1536 | + <span class="filename">calculator-atoi.asm</span> |
| 1537 | + <pre class="brush: asm;"> |
| 1538 | + ; Calculator (ATOI) |
| 1539 | + ; Compile with: nasm -f elf calculator-atoi.asm |
| 1540 | + ; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 calculator-atoi.o -o calculator-atoi |
| 1541 | + ; Run with: ./calculator-atoi 20 1000 317 |
| 1542 | + |
| 1543 | + %include 'functions.asm' |
| 1544 | + |
| 1545 | + SECTION .text |
| 1546 | + global _start |
| 1547 | + |
| 1548 | + _start: |
| 1549 | + |
| 1550 | + pop ecx ; first value on the stack is the number of arguments |
| 1551 | + mov edx, 0 ; initialise our data register to store additions |
| 1552 | + |
| 1553 | + nextArg: |
| 1554 | + cmp ecx, 0h ; check to see if we have any arguments left |
| 1555 | + jz noMoreArgs ; if zero flag is set jump to noMoreArgs label (jumping over the end of the loop) |
| 1556 | + pop eax ; pop the next argument off the stack |
| 1557 | + call atoi ; convert our ascii string to decimal integer |
| 1558 | + add edx, eax ; perform our addition logic |
| 1559 | + dec ecx ; decrease ecx (number of arguments left) by 1 |
| 1560 | + jmp nextArg ; jump to nextArg label |
| 1561 | + |
| 1562 | + noMoreArgs: |
| 1563 | + mov eax, edx ; move our data result into eax for printing |
| 1564 | + call iprintLF ; call our integer printing with linefeed function |
| 1565 | + call quit ; call our quit function |
| 1566 | + </pre> |
| 1567 | + <div class="output"> |
| 1568 | + <div class="inner"> |
| 1569 | + <span>~$ nasm -f elf calculator-atoi.asm</span> |
| 1570 | + <span>~$ ld -m elf_i386 calculator-atoi.o -o calculator-atoi</span> |
| 1571 | + <span>~$ ./calculator-atoi</span> |
| 1572 | + <span>1337</span> |
| 1573 | + </div> |
| 1574 | + </div> |
| 1575 | + </div> |
| 1576 | + |
| 1577 | + </article> |
| 1578 | + </div> |
| 1579 | + |
1471 | 1580 | </div> |
1472 | 1581 | </div> |
1473 | 1582 |
|
|
0 commit comments