您好 我在一个月前开始组装编程,在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
答案 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的一些力量的第一个很好的教程是: