Main
section .data
hello: db 'Hello world!',10 ; 'Hello world!' plus a linefeed character
helloLen: equ $-hello ; Length of the 'Hello world!' string
section .text
global _start
_start:
mov eax,4 ; The system call for write (sys_write)
mov ebx,1 ; File descriptor 1 - standard output
mov ecx,hello ; Put the offset of hello in ecx
mov edx,helloLen ; helloLen is a constant, so we don't need to say
; mov edx,[helloLen] to get it's actual value
int 80h ; Call the kernel
mov eax,1 ; The system call for exit (sys_exit)
mov ebx,0 ; Exit with return "code" of 0 (no error)
int 80h;
; Q1) Choose five numbers between 100 and 999. Write ALP by using conditional instructions
; for finding the largest of these five numbers and display the result as the output.
; section .text
; global _start ;must be declared for using gcc
; _start: ;tell linker entry point
; mov ecx, [num1]
; cmp ecx, [num2]
; jg check_third_num
; mov ecx, [num2]
; check_third_num:
; cmp ecx, [num3]
; jg check_fourth_num
; mov ecx, [num3]
; check_fourth_num:
; cmp ecx, [num4]
; jg check_fifth_num
; mov ecx,[num4]
; check_fifth_num:
; cmp ecx,[num5]
; jg _exit
; mov ecx,[num5]
; _exit:
; mov [largest], ecx
; mov ecx,msg
; mov edx, len
; mov ebx,1 ;file descriptor (stdout)
; mov eax,4 ;system call number (sys_write)
; int 0x80 ;call kernel
; mov ecx,largest
; mov edx, 4
; mov ebx,1 ;file descriptor (stdout)
; mov eax,4 ;system call number (sys_write)
; int 0x80 ;call kernel
; mov eax, 1
; mov ebx,0
; int 0x80
; section .data
; msg db "The largest digit is: "
; len equ $- msg
; num1 dq '999'
; num2 dq '200'
; num3 dq '809'
; num4 dq '909'
; num5 dq '591'
; segment .bss
; largest resb 4
; Q2) Choose a random number 20 ≤ R ≤ 100, write ALP by using loops for printing the numbers
; (i.e. from 1 to R) and display the result as the output.
; section .text
; global _start
; _start:
; mov ecx,msg
; mov edx,len
; mov eax,4
; mov ebx,1
; int 0x80
; mov eax,1
; mov [temp],eax
; loop_until_no._is_less_than_r:
; mov edi, num ; Argument: Address of the target string
; call int2str ; Get the digits of EAX and store it as ASCII
; sub edi, num ; EDI (pointer to the terminating NULL) - pointer to sum = length of the string
; mov [num_len], edi
; mov eax,4
; mov ebx,1
; mov ecx,num
; mov edx,[num_len]
; int 0x80
; mov eax,4
; mov ebx,1
; mov ecx,next_line
; mov edx,len1
; int 0x80
; mov eax,[temp]
; inc eax
; mov [temp],eax
; cmp eax,[r]
; jg _exit
; jmp loop_until_no._is_less_than_r
; _exit:
; mov eax, 1
; mov ebx, 0
; int 0x80
; int2str: ; Converts an positive integer in EAX to a string pointed to by EDI
; xor ecx, ecx
; mov ebx, 10
; .LL1: ; First loop: Save the remainders
; xor edx, edx ; Clear EDX for div
; div ebx ; EDX:EAX/EBX -> EAX Remainder EDX
; push dx ; Save remainder
; inc ecx ; Increment push counter
; test eax, eax ; Anything left to divide?
; jnz .LL1 ; Yes: loop once more
; .LL2: ; Second loop: Retrieve the remainders
; pop dx ; In DL is the value
; or dl, '0' ; To ASCII
; mov [edi], dl ; Save it to the string
; inc edi ; Increment the pointer to the string
; loop .LL2 ; Loop ECX times
; mov byte [edi], 0 ; Termination character
; ret ; RET: EDI points to the terminating NULL
; section .data
; msg db "Printing no from 1 to r: ",0xa
; len equ - next_line
; r db 100 ; value of r
; section .bss
; num resb 3
; num_len resd 2
; temp resb 3
; Q3) Write ALP for finding a factorial of number between 5 and 30 and display the result as the
; output.
; section .text
; global _start
; _start:
; mov ecx,msg
; mov edx,len
; mov ebx,1
; mov eax,4
; int 0x80
; mov eax,1
; mov ebx,1
; mov ecx,[fact]
; factorial_loop:
; mul ebx
; inc ebx
; loop factorial_loop
; ; Convert the number to a string
; mov edi, fac ; Argument: Address of the target string
; call int2str ; Get the digits of EAX and store it as ASCII
; sub edi, fac ; EDI (pointer to the terminating NULL) - pointer to sum = length of the string
; mov [len1], edi
; mov eax, 4
; mov ebx, 1
; mov ecx, fac
; mov edx, [len1]
; int 0x80
; ; Exit code
; mov eax, 1
; mov ebx, 0
; int 0x80
; int2str: ; Converts an positive integer in EAX to a string pointed to by EDI
; xor ecx, ecx
; mov ebx, 10
; .LL1: ; First loop: Save the remainders
; xor edx, edx ; Clear EDX for div
; div ebx ; EDX:EAX/EBX -> EAX Remainder EDX
; push dx ; Save remainder
; inc ecx ; Increment push counter
; test eax, eax ; Anything left to divide?
; jnz .LL1 ; Yes: loop once more
; .LL2: ; Second loop: Retrieve the remainders
; pop dx ; In DL is the value
; or dl, '0' ; To ASCII
; mov [edi], dl ; Save it to the string
; inc edi ; Increment the pointer to the string
; loop .LL2 ; Loop ECX times
; mov byte [edi], 0 ; Termination character
; ret ; RET: EDI points to the terminating NULL
; section .data
; msg db "Factorial : "
; len equ $-msg
; fact dd 6 ; input
; section .bss
; num resd 1
; fac resb 33
; len1 resd 3
; Q4) Choose a positive value 5 ≤ P ≤ 20, write ALP by defining a P-element array containing P
; random values and do the sum of these values in the array and display the result as the output.
; section .text
; global _start
; _start:
; mov eax,20
; mov ebx,0
; mov ecx,array
; top: ;loop
; add ebx,[ecx]
; inc ecx
; dec eax
; jnz top
; add ebx,'0'
; mov [sum],ebx
; mov ecx,msg
; mov edx,len
; mov eax,4
; mov ebx,1
; int 0x80
; mov ecx,sum
; mov edx,1
; mov ebx,1
; mov eax,4
; int 0x80
; ;exit
; mov eax,1
; mov ebx,0
; int 0x80
; section .data ;storing data
; msg db 'The sum of 20 elements:'
; len equ $-msg
; array db 1,2,3,4,5,6,7,8,9,-9,-8,-7,-6,-5,-4,-2,2,1
; sum db 0
; Q1) By taking one example program (i.e., any program done in labs so far), write the ALPs for the
; following addressing modes
; 1. Direct Addressing Mode.
; 2. Indirect Addressing Mode.
; 3. Immediate Addressing Mode.
; 4. Direct-Offset Addressing Mode.
; 5. Relative Addressing Mode.
; 6. Indexed Addressing Mode.
; 7. Register Addressing Mode.
; 8. Register Indirect Addressing Mode.
; 9. Auto-Increment Addressing Mode.
; 10. Auto-Decrement Addressing Mode.
; global _start
; section .text
; ;<======= Printing an integer =========>
; print_integer:
; mov ebx, 10
; div ebx ;dividing the number in eax to get remainder
; add edx, '0' ;converting the remainder to ascii
; push edx ;pushing the remainder to stack
; xor edx, edx ;clearing edx for the next value
; inc ecx ;increment of counter
; cmp eax, 0 ;checking if the quotient is 0 to terminate the loop
; jne print_integer ;if not 0 call function again
; xor eax, eax ;clearing eax
; reverse_array:
; pop dword [result + eax] ;popping elements from the stack and placing them in result
; inc eax ;keeping count of size of the string
; dec ecx ;from previous function number of elements in stack
; cmp ecx, 0
; jne reverse_array ;loops until stack is empty
; mov edx, eax
; mov ecx, result
; mov ebx, 1 ;file descriptor
; mov eax, 4 ;system write
; int 0x80 ;call kernel
; xor eax, eax ;clearing stack before returning to avoid segmentation fault
; xor ebx, ebx
; xor ecx, ecx
; xor edx, edx
; ret
; direct_addr:
; mov eax, [array_table] ;1
; add eax, [array_table + 4] ;4,5
; add eax, array_table[4]
; ret
; indirect_addr:
; mov ebx, num ;2
; add eax, [ebx]
; mov ebx, 100
; add eax, ebx ;7
; ret
; immed_addr:
; mov eax, 100
; add eax, 100 ;3
; ret
; reg_ind_addr:
; mov esi, array_table ;8
; mov eax, [esi]
; add eax, [esi + 4] ;6
; ret
; auto_inc: ;9
; mov ebx, array_table
; add eax, [ebx]
; add ebx, 4
; add eax, [ebx]
; ret
; auto_dec:
; mov ebx, array_table+4
; add eax, [ebx]
; sub ebx, 4
; add eax, [ebx]
; ret
; _start:
; mov ecx, msg1
; mov edx, len1
; mov ebx, 1 ;file descriptor
; mov eax, 4 ;system write
; int 0x80 ;call kernel
; xor eax, eax ;clearing stack
; xor ebx, ebx
; xor ecx, ecx
; xor edx, edx
; call direct_addr
; call print_integer
; mov ecx, msg2
; mov edx, len2
; mov ebx, 1 ;file descriptor
; mov eax, 4 ;system write
; int 0x80 ;call kernel
; xor eax, eax ;clearing stack
; xor ebx, ebx
; xor ecx, ecx
; xor edx, edx
; call indirect_addr
; call print_integer
; mov ecx, msg3
; mov edx, len3
; mov ebx, 1 ;file descriptor
; mov eax, 4 ;system write
; int 0x80 ;call kernel
; xor eax, eax ;clearing stack
; xor ebx, ebx
; xor ecx, ecx
; xor edx, edx
; call immed_addr
; call print_integer
; mov ecx, msg8
; mov edx, len8
; mov ebx, 1 ;file descriptor
; mov eax, 4 ;system write
; int 0x80 ;call kernel
; xor eax, eax ;clearing stack
; xor ebx, ebx
; xor ecx, ecx
; xor edx, edx
; call reg_ind_addr
; call print_integer
; mov ecx, msg9
; mov edx, len9
; mov ebx, 1 ;file descriptor
; mov eax, 4 ;system write
; int 0x80 ;call kernel
; xor eax, eax ;clearing stack
; xor ebx, ebx
; xor ecx, ecx
; xor edx, edx
; call auto_inc
; call print_integer
; mov ecx, msg10
; mov edx, len10
; mov ebx, 1 ;file descriptor
; mov eax, 4 ;system write
; int 0x80 ;call kernel
; xor eax, eax ;clearing stack
; xor ebx, ebx
; xor ecx, ecx
; xor edx, edx
; call auto_dec
; call print_integer
; Exit:
; ; Final next line
; mov ecx, msgb
; mov edx, lenb
; mov ebx, 1 ;file descriptor
; mov eax, 4 ;system write
; int 0x80 ;call kernel
; ; Exit
; mov eax, 1 ;system exit
; int 0x80 ;call kernel
; section .data
; num dd 100
; array_table dd 100, 100, 100, 100
; msg1 db 0xA,"InDirect and Register addressing : "
; len1 equ - msg2
; msg3 db 0xA,"Immediate addressing : "
; len3 equ - msg8
; msg9 db 0xA,"Auto-Increment addressing : "
; len9 equ - msg10
; msgb db 0xA, 0xD
; lenb equ $ - msgb
; section .bss ; space reserved for storing values
; result resb 1
; Q1) Write a program to generate the Fibonacci series in ALP.
; Sample output:
; Enter the number range: 15
; FIBONACCI SERIES: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
; SOLUTION:
; section .text
; global _start
; _start:
; mov eax , 3
; mov ebx , 0
; mov ecx , range
; mov edx , 3
; int 0x80
; ; Printing the initial message
; mov eax , 4
; mov ebx , 1
; mov ecx , msg
; mov edx , len
; int 0x80
; ; Printing the 1st number
; mov eax , [x]
; mov edi, sum
; call int_str
; sub edi, sum
; mov [sum_len], edi
; mov eax , 4
; mov ebx , 1
; mov ecx , sum
; mov edx , [sum_len]
; int 0x80
; mov eax , 4
; mov ebx , 1
; mov ecx , msg2
; mov edx , len2
; int 0x80
; ; Printing the 2nd number
; mov eax , [y]
; mov edi, sum
; call int_str
; sub edi, sum
; mov [sum_len], edi
; mov eax , 4
; mov ebx , 1
; mov ecx , sum
; mov edx , [sum_len]
; int 0x80
; mov eax , 4
; mov ebx , 1
; mov ecx , msg2
; mov edx , len2
; int 0x80
; ; The Actual program goes here
; mov edx, range ; the string I have taken
; call str_int
; mov ecx , eax
; sub ecx , 2
; fib_loop:
; mov [range] , ecx
; mov eax , [x]
; mov ebx , [y]
; add eax , ebx
; mov ebx , [y]
; mov [x] , ebx
; mov [y] , eax
; mov edi, sum
; call int_str
; sub edi, sum
; mov [sum_len], edi
; mov eax , 4
; mov ebx , 1
; mov ecx , sum
; mov edx , [sum_len]
; int 0x80
; mov eax , 4
; mov ebx , 1
; mov ecx , msg2
; mov edx , len2
; int 0x80
; mov ecx , [range]
; dec ecx
; jne fib_loop
; mov eax, 1
; int 0x80
; str_int: ; Converts an string in EDX to a integer stored in eax.
; xor eax, eax ; clear off anything in eax
; .top:
; movzx ecx, byte [edx] ; get each character of string in each iteration
; inc edx
; cmp ecx, '0' ; If you reach end of string, then you're done.
; jb .done
; cmp ecx, '9'
; ja .done
; sub ecx, '0' ; converting character to integer
; imul eax, 10 ; multiply the result obtained till now by ten
; add eax, ecx ; add in current digit
; jmp .top ; loop until done.
; .done:
; ret
; int_str: ; Converts an positive integer in EAX to a string pointed to
; by EDI ("sum" in this case).
; xor ecx, ecx
; mov ebx, 10
; .LL1:
; xor edx, edx
; div ebx
; push dx
; inc ecx
; test eax, eax
; jnz .LL1
; .LL2:
; pop dx
; or dl, '0'
; mov [edi], dl
; inc edi
; loop .LL2
; mov byte [edi], 0
; ret
; section .data
; x dd 0
; y dd 1
; ;range dd 15
; msg db "The Fibonacci Sequence is : "
; len equ -msg2
; msg3 db "Enter the Range : "
; len3 equ $-msg3
; segment .bss
; sum resb 40
; sum_len resd 1
; range resb 3
; ; range_len resd 10
; Q2) Write an ALP to check given number is Perfect number or not. A perfect number is a
; positive integer that is equal to the sum of its positive divisors, excluding the number
; itself. 6 is a positive number and its divisor is 1,2,3 and 6 itself. 1+2+3 = 6 which is equal
; to number itself.
; SOLUTION:
; section .data
; msg db "8128 is " ; the no. I am taking
; len equ - msg1
; msg2 db 'not perfect',0xa
; len2 equ $ - msg2
; num1 dd 8128 ;input any number here
; section .bss
; sum times 2 resb 2
; section .text
; global _start
; _start:
; mov eax,0
; mov [sum],eax
; mov edx,len ;message length
; mov ecx,msg ;message to write
; mov ebx,1 ;file descriptor (stdout)
; mov eax,4 ;system call number (sys_write)
; int 0x80 ;call kernel
; mov eax,[num1]
; mov ecx,1
; check:
; mov edx,[num1]
; cmp ecx,edx
; je perfect
; xor edx,edx
; mov eax,[num1]
; mov ebx,ecx
; div ebx
; cmp dx,0
; je sig
; level:
; inc ecx
; jmp check
; perfect:
; mov edx,[num1]
; mov eax,[sum]
; cmp edx,eax
; je Yes
; jmp No
; sig:
; add [sum],ecx
; jmp level
; Yes:
; mov edx,len1 ;message length
; mov ecx,msg1 ;message to write
; mov ebx,1 ;file descriptor (stdout)
; mov eax,4 ;system call number (sys_write)
; int 0x80 ;call kerne
; jmp exit
; No:
; mov edx,len2 ;message length
; mov ecx,msg2 ;message to write
; mov ebx,1 ;file descriptor (stdout)
; mov eax,4 ;system call number (sys_write)
; int 0x80 ;call kerne
; exit:
; mov eax,1 ;system call number (sys_exit)
; int 0x80 ;call kernel
; Q3) Write an ALP program to convert a decimal number to binary.
; SOLUTION:
; segment .data
; msg db "Binary representation of the no. 49 is:"
; len equ $- msg
; num dd 49 ;input any no. here
; segment .bss
; sum resb 40
; sum_len resd 1
; section .text
; global _start ;must be declared for using gcc
; _start: ;tell linker entry point
; mov eax, [num]
; mov edi, sum ; Argument: Address of the target string
; call int_str
; sub edi, sum
; mov [sum_len], edi
; mov ecx, msg
; mov edx, len
; mov ebx,1 ;file descriptor (stdout)
; mov eax,4 ;system call number (sys_write)
; int 0x80
; mov eax, 4
; mov ebx, 1
; mov ecx, sum
; mov edx, [sum_len]
; int 0x80
; exit:
; mov eax, 1
; xor ebx, ebx
; int 0x80
; int_str: ; Converts an positive integer in EAX to a string pointed to
; by EDI
; xor ecx, ecx
; mov ebx, 2 ; divided by 2 to covert into binary
; .LL1: ; First loop: Save the remainders
; xor edx, edx ; Clear EDX for div
; div ebx ; EDX:EAX/EBX -> EAX Remainder EDX
; push dx ; Save remainder
; inc ecx ; Increment push counter
; test eax, eax ; Anything left to divide?
; jnz .LL1 ; Yes: loop once more
; .LL2: ; Second loop: Retrieve the remainders
; pop dx ; In DL is the value
; or dl, '0' ; To ASCII
; mov [edi], dl ; Save it to the string
; inc edi ; Increment the pointer to the string
; loop .LL2 ; Loop ECX times
; mov byte [edi], 0
; ret
; Q1) Given a positive number, write ALP for verifying whether it is a prime number or not,
; and display the result as the output.
; Solution:
; section .data
; msg1 db "The number is a prime number.", 0xa, 0xd
; len1 equ - msg2
; section .text
; global _start
; _start:
; mov ecx, 12 ;enter any number here
; mov eax, ecx
; mov bx, 2
; div bx
; mov esi, eax
; division_loop:
; mov eax, ecx
; xor edx, edx
; cmp esi, 1
; je is_prime
; mov ebx, esi
; div ebx
; dec esi
; cmp edx, 0
; jne division_loop
; is_not_prime:
; mov eax, 4
; mov ebx, 1
; mov ecx, msg2
; mov edx, len2
; int 0x80
; jmp exit
; is_prime:
; mov eax, 4
; mov ebx, 1
; mov ecx, msg1
; mov edx, len1
; int 0x80
; jmp exit
; exit:
; mov eax, 1
; mov ebx, 0
; int 0x80
; Output:
; Q2) Given a positive number, write ALP for verifying whether it is an Armstrong number or
; not, and display the result as the output. (An Armstrong number is an n-digit number such
; that sum of its digits raised to the power n is the number itself. Armstrong numbers are 1, 2,
; 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8202, 9474, 54748, etc.. For eg: 153 because 13 +
; 53 + 33 = 153, 1634 because 14 + 64 + 34 + 44 = 1634, and 54748 because 55 + 45 + 75 + 45 +
; 85 = 54748.)
; Solution:
; section .data
; msg1 db "It is a Armstrong number", 0xa, 0xc
; len1 equ - msg2
; num dq 153
; sum dq 0
; digits dq 3
; it dq 0
; section .text
; global _start
; power:
; mov ecx, [digits]
; mov esi, eax
; mov eax, 1
; p_loop:
; dec ecx
; mul esi
; cmp ecx, 0
; jg p_loop
; ret
; _start:
; mov eax, [num]
; xor ecx, ecx
; div_loop:
; inc ecx
; mov esi, 10
; xor edx, edx
; idiv esi
; push edx
; cmp eax, 0
; jnz div_loop
; mov [digits], ecx
; mov [it], ecx
; sum_it:
; ; decrement it
; mov ecx, [it]
; dec ecx
; mov [it], ecx
; ; perform power and addition
; pop eax
; call power
; add [sum], eax
; mov ecx, [it]
; cmp ecx, 0
; jnz sum_it
; mov eax, [sum]
; check:
; mov eax, [sum]
; mov ebx, [num]
; cmp eax, ebx
; jne negative
; affirmitive:
; mov eax, 4
; mov ebx, 1
; mov ecx, msg1
; mov edx, len1
; int 0x80
; jmp exit
; negative:
; mov eax, 4
; mov ebx, 1
; mov ecx, msg2
; mov edx, len2
; int 0x80
; ret
; exit:
; mov eax, 1
; mov ebx, 0
; int 0x80
; Output:
; number = 153
; number = 179
; Q3) Given a positive number, write ALP for verifying whether it is a palindrome number or
; not, and display the result as the output. (A palindrome number is a number that remains
; the same when its digits are reversed. For eg: 16461)
; Solution:
; section .data
; msg1 db "Yes, it is a palindrome number", 0xa, 0xc
; len1 equ $ - msg1
; msg2 db "No, it is not a palindrome number", 0xa, 0xc
; len2 equ $ - msg2
; num dq 525
; rev_num dq 0
; digits dq 3
; it dq 0
; section .text
; global _start
; _start:
; mov eax, [num]
; xor ecx, ecx
; div_loop:
; inc ecx
; mov esi, 10
; xor edx, edx
; idiv esi
; push edx
; cmp eax, 0
; jnz div_loop
; xor edx, edx
; mov esi, 1
; mov ebx, 1
; create_rev_number:
; dec ecx
; mov eax, esi
; imul ebx
; mov esi, eax
; mov ebx, 10
; pop eax
; imul esi
; mov edx, [rev_num]
; add edx, eax
; mov [rev_num], edx
; cmp ecx, 0
; jnz create_rev_number
; check:
; mov eax, [num]
; cmp eax, edx
; jne negative
; affirmitive:
; mov eax, 4
; mov ebx, 1
; mov ecx, msg1
; mov edx, len1
; int 0x80
; jmp exit
; negative:
; mov eax, 4
; mov ebx, 1
; mov ecx, msg2
; mov edx, len2
; int 0x80
; ret
; exit:
; mov eax, 1
; mov ebx, 0
; int 0x80
; Output:
; number = 525
; number = 127
; Q4) Given a string, write ALP for counting number of words, characters (including spaces),
; vowels, consonants, and display the result as the output. (For eg: given ‘Hello IIITDM
; Kancheepuram’, then program should display number of words = 3, characters = 25, vowels
; = 10, consonants = 13)
; Sol.
; ; print string
; %macro write_string 2
; mov eax, 4
; mov ebx, 1
; mov ecx, %1
; mov edx, %2
; int 0x80
; %endmacro
; section .data
; msg1 db "words: "
; len1 equ $-msg1
; msg2 db "characters: "
; len2 equ -msg3
; msg4 db "consonants: "
; len4 equ -newline
; string db "i love india"
; len equ $-string
; words dq 0
; chars dq 0
; vowels dq 0
; consonants dq 0
; section .text
; global _start
; _start:
; mov ecx, len ; charachters (non-space)
; mov ebx, 0 ; vowel
; mov edx, 0 ; words
; mov esi, 0 ; consonants
; process_space:
; inc edx
; dec ecx
; inc esi
; compute:
; mov al, [string+esi]
; cmp al, ' '
; je process_space
; cmp al, 'a'
; je vowel
; cmp al, 'e'
; je vowel
; cmp al, 'i'
; je vowel
; cmp al, 'o'
; je vowel
; cmp al, 'u'
; je vowel
; jmp not_vowel
; vowel:
; inc ebx
; not_vowel:
; inc esi
; loop compute
; ; we have the vowels
; mov [vowels], ebx
; ; get number of consonants
; mov ecx, len
; sub ecx, edx ; subtract the number of spaces
; sub ecx, ebx ; subtract the number of vowels
; mov [consonants], ecx
; ; get number of words
; inc edx
; ; process the last word
; mov [words], edx
; ; get number of charachters (non-space)mov eax, [vowels]
; mov ebx, [consonants]
; add eax, ebx
; mov [chars], eax
; write_string msg1, len1
; mov eax, [words]
; call print_int
; write_string newline, linelen
; write_string msg2, len2
; mov eax, [chars]
; call print_int
; write_string newline, linelen
; write_string msg3, len3
; mov eax, [vowels]
; call print_int
; write_string newline, linelen
; write_string msg4, len4
; mov eax, [consonants]
; call print_int
; write_string newline, linelen
; exit:
; mov eax, 1
; mov ebx, 0
; int 0x80