新装配;我是否遵守此计划的正确代码标准?如果没有,欢迎提示

时间:2011-05-03 06:05:18

标签: performance assembly code-analysis masm

您好 我在一个月前开始组装编程,在stackoverflow的几本书和社区的帮助下,我一直在ASM编写程序。我写了这个程序来比较2个数字并打印哪个数字更大。我想知道我是否正确地做了这些事情。欢迎任何性能优化提示!

.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

3 个答案:

答案 0 :(得分:2)

有意义的标签名称怎么样?

答案 1 :(得分:1)

一个小的优化可能是将所有比较结束的WriteConsoleA的公共调用移到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
.
.

答案 2 :(得分:0)

许多事情要做得更好。首先,你正在使用Masm,但没有收获它的力量。注意到的第一件事是你不使用invoke或procs,但坚持使用push / call模型和直接的代码流。

我会高度推荐iczelion的精彩教程:

http://win32assembly.online.fr/

看到Masm的一些力量的第一个很好的教程是:

http://win32assembly.online.fr/tut2.html