.text .global _start _start: mov $buf, %rsi readloop: ## Read character in. mov $0, %rax mov $0, %rdi mov $1, %rdx syscall ## Check return value; exit if not equal to one. cmp $1, %rax jne exit ## Move read character into RAX and increment buffer position. movzx (%rsi), %rax inc %rsi ## Loop if read character wasn't a line feed. cmp $0x0a, %rax jne readloop ## Start reading words at start of buffer with zero length mov $buf, %rsi mov $0, %rdx wordloop: ## Copy character into R8 movzx (%rsi, %rdx), %r8 ## Print the word if the character is a space or a newline cmp $0x20, %r8 je doword cmp $0x0a, %r8 je doword ## Increment word length and loop inc %rdx jmp wordloop doword: ## Skip operator checks if word length is greater than 1 cmp $1,%rdx jg donum ## Check for operators and jump to appropriate procedure movzx (%rsi),%rax cmp $0x2b,%rax je doplus cmp $0x2d,%rax je dominus cmp $0x2a,%rax je domultiply cmp $0x2f,%rax je dodivide donum: mov $0, %rax mov $0, %rcx numloop: ## Multiply current value by ten imul $10, %rax ## Add numeric value of digit movzx (%rsi, %rcx), %rbx sub $0x30, %rbx add %rbx, %rax ## Increment index and loop if not at end of word inc %rcx cmp %rcx, %rdx jg numloop push %rax jmp endword doplus: pop %rbx pop %rax add %rbx,%rax push %rax jmp endword dominus: pop %rbx pop %rax sub %rbx,%rax push %rax jmp endword domultiply: pop %rbx pop %rax imul %rbx,%rax push %rax jmp endword dodivide: pop %rbx pop %rax mov $0,%rdx idiv %rbx push %rax ## Restore RDX mov $1,%rdx endword: ## Handle end of line cmp $0x0a, %r8 je endline ## Add the word length to RSI and increment until non-space is ## found add %rdx, %rsi spaceloop: inc %rsi mov (%rsi), %rax cmp $0x20, %rax je spaceloop ## Zero the word length then return to the word loop. mov $0, %rdx jmp wordloop endline: mov $buf,%rsi add $100,%rsi mov $1,%rcx ## Add line feed at end of buffer movb $0x0a,(%rsi) ## Set base and pop value mov $10,%r8 pop %rax formatloop: dec %rsi inc %rcx ## Divide RAX by ten to get unformatted value (RAX) and current ## digit value (RDX) mov $0,%rdx idiv %r8 ## Write character for digit into buffer add $0x30,%rdx movb %dl,(%rsi) ## Loop if the unformatted value is non-zero cmp $0,%rax jne formatloop ## Print value mov $1,%rax mov $1,%rdi mov %rcx,%rdx syscall ## Return to top jmp _start exit: ## Exit with code 0 mov $60, %rax mov $0, %rdi syscall .bss buf: .skip 100