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

发布于 2024-11-04 17:39:05 字数 4360 浏览 1 评论 0原文

你好 我一个月前开始汇编编程,在几本书和 stackoverflow 社区的帮助下,我一直在用 ASM 编写程序。我编写这个程序是为了比较两个数字并打印哪个数字更大。我想知道我做的事情是否正确。欢迎任何性能优化建议!

.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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

给不了的爱 2024-11-11 17:39:05

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

How about meaningful label names?

几味少女 2024-11-11 17:39:05

一个小的优化可能是将所有比较都以 L3 之后结束的通用调用移至 WriteConsoleA:

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

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
.
.
打小就很酷 2024-11-11 17:39:05

很多很多事情需要做得更好。首先,你正在使用 Masm,但没有收获它的力量。人们注意到的第一件事是您不使用调用或过程,而是坚持使用推送/调用模型和直接代码流。

强烈推荐 iczelion 的精彩教程:

http://win32 assembly.online.fr/

一个很好的第一个教程,可以了解 Masm 的一些功能:

http://win32 assembly.online.fr/tut2.html

Many many things to do better. First of all, you are using Masm, but not harvesting its power. The first thing that one notices is that you do not use invoke or procs, but stick with the push/call model and direct flow of code.

I would highly recommend iczelion's great tutorials :

http://win32assembly.online.fr/

A nice first tutorial to see some of Masm's power is :

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文