Search code examples
performanceassemblycode-analysismasm

New to assembly; Am I complying with proper code standards with this program? if not, tips are welcome


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

Solution

  • 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
    .
    .