I'd like to know what the issue could be here in terms of what I'm doing wrong, and how I could fix it?
Most of my experience is in C++, but I'm just learning assembly.
The goal of the program is to simply take in a lowercase string (from stdin - i.e., the keyboard), convert it to uppercase, and then print it. It's as simple as that.
bits 32 [section .bss] buf: resb 1024 ;allocate 1024 bytes of memory to buf [section .data] ;************* ;* CONSTANTS * ;************* ;ASCII comparison/conversion LowercaseA: equ 0x61 LowercaseZ: equ 0x7A SubToUppercase: equ 0x20 ;IO specifiers/descriptors EOF: equ 0x0 sys_read: equ 0x3 sys_write: equ 0x4 stdin: equ 0x0 stdout: equ 0x1 stderr: equ 0x2 ;Kernel Commands/Program Directives _exit: equ 0x1 exit_success: equ 0x0 execute_cmd: equ 0x80 ;Memory Usage buflen: equ 0x400 ;1KB of memory max_num_write_len: equ 0xFFFF ;32-bit max ;***************** ;* NON-CONSTANTS * ;***************** iteration_count: dd 0 query : db "Please enter a string of lowercase characters, and I will output them for you in uppercase ^.^: ", 10 querylen : equ $-query [section .text] global _start extern _printf ;=========================================== ; Entry Point ;=========================================== _start: nop ;keep GDB from complaining call AskUser call Read call SetupBuf call Scan call Write jmp Exit ;=========================================== ; IO Instructions ;=========================================== Read: mov eax, sys_read ;we're going to read in something mov ebx, stdin ;where we obtain this is from stdin mov ecx, buf ;read data into buf mov edx, buflen ;amount of data to read int execute_cmd ;invoke kernel to do its bidding ret Write: mov eax, sys_write ;we're going to write something mov ebx, stdout ;where we output this is going to be in stdout mov ecx, buf ;buf goes into ecx; thus, whatever is in ecx gets written out to mov edx, buflen ;write the entire buf int execute_cmd ;invoke kernel to do its bidding ret AskUser: mov eax, sys_write mov ebx, stdout mov ecx, query mov edx, querylen int execute_cmd ret ;PROC: takes an integer to print; be sure to push that integer before calling print_num: push ecx ;save the loop count in edx pop ecx ;grab data to print, store in ecx mov eax, sys_write mov ebx, stdout mov edx, max_num_write_len ;store the num write len in edx int execute_cmd ;call kernel pop ecx ;grab the loop count again sub esp, 8 ;subtract 8 from esp (the stack pointer register) to ensure that it's put back in its proper place ret ;ENDPROC ;=========================================== ; Program Preperation ;=========================================== SetupBuf: mov ecx, esi ;place the number of bytes read into ecx mov ebp, buf ;place the address of buf into ebp mov dword [ebp + ecx], 0 ;null terminate string dec ebp ;decrement buf by 1 to prevent "off by one" error ret ;=========================================== ; Conversion Routines ;=========================================== ToUpper: sub dword [ebp + ecx], SubToUppercase ;grab the address of buf and sub its value to create uppercase character ret Scan: mov eax, iteration_count ;store iteration_count in eax push eax ;whatever value exists in iteration_count as loop count call print_num ;print the current iteration within the loop cmp dword [ebp + ecx], LowercaseA ;Test input char against lowercase 'a' jb ToUpper ;If below 'a' in ASCII, then is not lowercase - goto ToLower cmp dword [ebp + ecx], LowercaseZ ;Test input char against lowercase 'z' ja ToUpper ;If above 'z' in ASCII, then is not lowercase - goto ToLower dec ecx ;decrement ecx by one, so we can get the next character add dword [iteration_count], 1 ;increment the __value__ in iteration count by 1 jnz Scan ;if ecx != 0, then continue the process ret ;=========================================== ;Next: ; dec ecx ;decrement ecx by one ; jnz Scan ;if ecx != 0 scan ; ret ;=========================================== Exit: mov eax, _exit mov ebx, exit_success int execute_cmd
NASM uses Intel syntax, so for those of you who are use to FASM or TASM but not NASM, it should be pretty easy to decipher.