GAS LISTING da.s page 1 1 .file "da.s" 2 .data 3 .align 4 4 num0: 5 0000 00000000 .long 0 6 num1: 7 0004 00000000 .long 0 8 num2: 9 0008 00000000 .long 0 10 total: 11 000c 00000000 .long 0 12 radix: 13 0010 0A000000 .long 10 14 buff0: 15 0014 31202020 .ascii "1 " 15 2020 16 001a 20706C75 .ascii " plus " 16 7320 17 buff1: 18 0020 32202020 .ascii "2 " 18 2020 19 0026 20706C75 .ascii " plus " 19 7320 20 buff2: 21 002c 33202020 .ascii "3 " 21 2020 22 0032 20657175 .ascii " equals " 22 616C7320 23 buff3: 24 003a 36202020 .ascii "6 " 24 2020 25 0040 0A00 .string "\n" 26 0042 00000000 .zero 6 26 0000 27 .section .rodata 28 .text 29 .align 4 30 .globl main 31 .type main,@function 32 # 33 # Recursive number converter 34 # Usage: da num0 num1 num2 35 # 36 main: 37 0000 55 pushl %ebp # Save the old frame pointer 38 0001 89E5 movl %esp, %ebp # Start a new fram here 39 0003 6A2D pushl $45 # Setup buffer size 40 0005 68140000 pushl $buff0 # buffer start address and 40 00 41 000a 6A01 pushl $1 # file descriptor for standard out 42 000c E8FCFFFF call write # and use low-level write service 42 FF 43 0011 83C40C addl $12, %esp # Reset stack pointer 44 0014 8B450C movl 12(%ebp), %eax # Get the pointer to the start of argv 45 0017 8B7004 movl 4(%eax),%esi # Get the ptr to the second argument 46 001a E8940000 call getarg # Fetch and convert ASCII argument 46 00 GAS LISTING da.s page 2 47 001f A3000000 movl %eax, num0 # Save the binary 1st number 47 00 48 0024 8B450C movl 12(%ebp), %eax # Get the pointer to the start of argv 49 0027 8B7008 movl 8(%eax),%esi # Get the ptr to the second argument 50 002a E8840000 call getarg # Fetch and convert ASCII argument 50 00 51 002f A3040000 movl %eax, num1 # Save the 2nd binary number 51 00 52 0034 8B450C movl 12(%ebp), %eax # Get the pointer to the start of argv 53 0037 8B700C movl 12(%eax),%esi # Get the ptr to the second argument 54 003a E8740000 call getarg # Fetch and convert ASCII argument 54 00 55 003f A3080000 movl %eax, num2 # Save the 3rd binary number 55 00 56 0044 A1000000 movl num0, %eax # Fetch the first binary number 56 00 57 0049 03050400 addl num1, %eax # Add the second binary number 57 0000 58 004f 03050800 addl num2, %eax # Add the third binary number 58 0000 59 0055 A30C0000 movl %eax, total # Save result 59 00 60 005a 8B0D1000 movl radix, %ecx # Display the number in the specified radix 60 0000 61 0060 8D3D1400 leal buff0, %edi # Point to most significant position 61 0000 62 0066 A1000000 movl num0, %eax # Fetch the first binary number 62 00 63 006b E8660000 call bin2ascii # and put the ASCII digits in the buffer 63 00 64 0070 8D3D2000 leal buff1, %edi # Point to most significant position 64 0000 65 0076 A1040000 movl num1, %eax # Fetch the second binary number 65 00 66 007b E8560000 call bin2ascii # and put the ASCII digits in the buffer 66 00 67 0080 8D3D2C00 leal buff2, %edi # Point to most significant position 67 0000 68 0086 A1080000 movl num2, %eax # Get the third binary number 68 00 69 008b E8460000 call bin2ascii # and put the ASCII digits in the buffer 69 00 70 0090 8D3D3A00 leal buff3, %edi # Point to most significant position 70 0000 71 0096 A10C0000 movl total, %eax # Fetch result 71 00 72 009b E8360000 call bin2ascii # and put the ASCII digits in the buffer 72 00 73 74 00a0 6A2D pushl $45 # Do 75 00a2 68140000 pushl $buff0 # write 75 00 76 00a7 6A01 pushl $1 # system 77 00a9 E8FCFFFF call write # service 77 FF 78 00ae 83C40C addl $12, %esp # and reset stack pointer 79 .L1: GAS LISTING da.s page 3 80 00b1 C9 leave 81 00b2 C3 ret 82 # 83 # Get the argument from the command line and, save the ASCII 84 # digits in the data area, and convert the digits to a binary number 85 # 86 # %esi == start of ASCII command line string 87 # %eax == return value of binary number 88 # 89 getarg: 90 00b3 55 pushl %ebp 91 00b4 89E5 movl %esp, %ebp 92 00b6 31C0 xorl %eax,%eax # Begin with a 0 value 93 nextdigit: 94 00b8 0FBE0E movsbl (%esi), %ecx # Get the ASCII number 95 00bb 80F930 cmpb $'0', %ecx # Is it less than an ASCII 0? 96 00be 7C14 jl numend # Yes, assume end of ASCII digits 97 00c0 80F939 cmpb $'9', %ecx # No, is it greater than a '9'? 98 00c3 7F0F jg numend # Yes, probably garbage 99 00c5 83E930 subl $'0', %ecx # Make the new digit binary 100 00c8 BA0A0000 movl $10, %edx # and move the 100 00 101 00cd F7E2 mul %edx # old number over one digit 102 00cf 01C8 addl %ecx, %eax # Add the new low order digit to it 103 00d1 46 inc %esi # Adjust pointer to next possible digit 104 00d2 EBE4 jmp nextdigit # and go look 105 numend: 106 00d4 C9 leave 107 00d5 C3 ret 108 109 # 110 # Convert binary to ASCII and put digits in buffer 111 # 112 # %eax == value of binary number 113 # %ecx == radix value of the ASCII number 114 # %edi == start of ASCII output buffer 115 # 116 bin2ascii: # Let's forget frame pointers 117 00d6 83F800 cmp $0, %eax # Is it a negative number? 118 00d9 7906 jns b2a1 # No - work the number directly 119 00db C6072D movb $'-', (%edi) # Yes - begin with the minus sign 120 00de 47 inc %edi # and point to the next position 121 00df F7D8 neg %eax # Make the negative number positive 122 b2a1: # Entry point for recursion 123 00e1 31D2 xor %edx, %edx # Clear the old remainder 124 00e3 F7F1 div %ecx # Use base to strip off least significant digit 125 00e5 52 push %edx # Save intermediate result 126 00e6 21C0 and %eax, %eax # Are there more digits? 127 00e8 7405 jz b2a2 # No, time to unwind 128 00ea E8F2FFFF call b2a1 # Yes, then stack the next most significant digit 128 FF 129 b2a2: # Output the results left to right 130 00ef 58 pop %eax # Fetch the next least significant digit 131 00f0 83C030 add $'0', %eax # Make it ASCII 132 00f3 83F839 cmp $'9', %eax # Does the result call for a Hex or greater digit 133 00f6 7E03 jle b2a3 # No, just output the ASCII digit 134 00f8 83C007 add $7, %eax # Yes, then move up to the alpha characters GAS LISTING da.s page 4 135 b2a3: 136 00fb 8807 movb %al, (%edi) # Copy the ASCII char to the output buffer 137 00fd 47 inc %edi # moving from the left to the right 138 00fe C3 ret # Remember, no frame pointers GAS LISTING da.s page 5 DEFINED SYMBOLS *ABS*:00000000 da.s da.s:4 .data:00000000 num0 da.s:6 .data:00000004 num1 da.s:8 .data:00000008 num2 da.s:10 .data:0000000c total da.s:12 .data:00000010 radix da.s:14 .data:00000014 buff0 da.s:17 .data:00000020 buff1 da.s:20 .data:0000002c buff2 da.s:23 .data:0000003a buff3 da.s:36 .text:00000000 main da.s:89 .text:000000b3 getarg da.s:116 .text:000000d6 bin2ascii da.s:93 .text:000000b8 nextdigit da.s:105 .text:000000d4 numend da.s:122 .text:000000e1 b2a1 da.s:129 .text:000000ef b2a2 da.s:135 .text:000000fb b2a3 UNDEFINED SYMBOLS write