Hello I started assembly programming a month ago, and with the help of a few books and the community here at stackoverflow, I have been writing programs in ASM. I wrote this program to compare 2 numbers and print which number is greater. I was wondering if im doing the stuff right. Any performance optimization tips are welcome!
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
.data
prompt BYTE "Enter First Number:",13,10,0
prompt1 BYTE "Enter Second Number:",13,10,0
prompt2 BYTE "First number greater than second number",13,10,0
prompt3 BYTE "Second number greater than first number",13,10,0
prompt4 BYTE "Both numbers are equal",13,10,0
.data?
outputHandle DWORD ?
inputHandle DWORD ?
nCharsWritten DWORD ?
len1 DWORD ?
buf1 BYTE 200 DUP(?)
len2 DWORD ?
buf2 BYTE 200 DUP(?)
num1 DWORD ?
num2 DWORD ?
.code
main PROC
;get output and input handles
;first get output handle
push STD_OUTPUT_HANDLE
CALL GetStdHandle
;save output handle
mov outputHandle, eax
;now get input handle
push STD_INPUT_HANDLE
CALL GetStdHandle
;save input handle
mov inputHandle, eax
;Ask User for First Number
push NULL
push OFFSET nCharsWritten
mov eax, LENGTHOF prompt
dec eax
push eax
push OFFSET prompt
push outputHandle
CALL WriteConsoleA
;Input First Number
push NULL
push OFFSET len1
push 200
push OFFSET buf1
push inputHandle
CALL ReadConsoleA
;prompt user for second number
push NULL
push OFFSET nCharsWritten
mov eax, LENGTHOF prompt1
dec eax
push eax
push OFFSET prompt1
push outputHandle
CALL WriteConsoleA
;Input Second Number
push NULL
push OFFSET len2
push 200
push OFFSET buf2
push inputHandle
CALL ReadConsoleA
;Strip CRLF
push OFFSET buf1
CALL StripLF
push OFFSET buf2
CALL StripLF
;Convert OEM to char
push OFFSET buf1
push OFFSET buf1
CALL OemToChar
push OFFSET buf2
push OFFSET buf2
CALL OemToChar
;Convert string to decimal
push OFFSET buf1
CALL atodw
mov num1, eax
push OFFSET buf2
CALL atodw
mov num2, eax
;Clear ZF
or al,1
;Clear CF
clc
;Compare the two numbers
mov eax, num2
cmp eax, num1
jl L1 ;jump if num2 is less than num1
jg L2 ;jump if num2 is greater than num1
;both equal
;write to console
push NULL
push OFFSET nCharsWritten
push LENGTHOF prompt4
push OFFSET prompt4
push outputHandle
CALL WriteConsoleA
jmp L3
L1:
;Write to console
push NULL
push OFFSET nCharsWritten
push LENGTHOF prompt2
push OFFSET prompt2
push outputHandle
CALL WriteConsoleA
jmp L3
L2:
;Write to console
push NULL
push OFFSET nCharsWritten
push LENGTHOF prompt3
push OFFSET prompt3
push outputHandle
CALL WriteConsoleA
jmp L3
L3:
push NULL
CALL ExitProcess
main ENDP
END main
A small optimization could be to move the common call to WriteConsoleA that all comparisons end with to after L3:
.
.
;Compare the two numbers
mov eax, num2
cmp eax, num1
jl L1 ;jump if num2 is less than num1
jg L2 ;jump if num2 is greater than num1
;both equal
;write to console
push NULL
push OFFSET nCharsWritten
push LENGTHOF prompt4
push OFFSET prompt4
push outputHandle
; CALL WriteConsoleA <- remove
jmp L3
L1:
;Write to console
push NULL
push OFFSET nCharsWritten
push LENGTHOF prompt2
push OFFSET prompt2
push outputHandle
; CALL WriteConsoleA <- remove
jmp L3
L2:
;Write to console
push NULL
push OFFSET nCharsWritten
push LENGTHOF prompt3
push OFFSET prompt3
push outputHandle
; CALL WriteConsoleA ; <- remove
; jmp L3 ; unnecessary unless new code added in-between
L3:
CALL WriteConsoleA
push NULL
CALL ExitProcess
.
.