消息框中的多行输出,汇编语言

时间:2017-09-27 05:00:01

标签: assembly messagebox inline-assembly

我创建了这个程序来计算毕业所需的学分,从基本用户输入的名称,学位,学位所需学分和当前学分获得。汇编对我来说是新的,到目前为止,我们只学习了I / O和消息框的基础知识,在本例中是“标签”。虽然我只被要求通过消息框输出学位所需的学分我认为探索如何显示用户输入的名称和学位可能会很有趣。我的程序在一个消息框中显示名称和学位,在另一个消息框中显示所需的学分。我的问题是,是否可以将两个框组合成一个显示两组输出的框?提前谢谢。

.586
.MODEL FLAT

INCLUDE io.h            ; header file for input/output

.STACK 4096
.DATA

student_name DWORD   ?
student_degree DWORD   ?
credits_needed DWORD    ?
credits_completed DWORD ?

prompt1 BYTE    "Please enter your name and degree: ", 0
stringIn    BYTE    80 DUP (?)
displayLbl  BYTE    "Student Name - Student Degree...", 0
stringOut   BYTE    80 DUP (?)

prompt2 BYTE    "How many credits in your degree field?", 0
prompt3 BYTE    "Lastly, how many credits have your earned?", 0
string      BYTE    60 DUP (?)
resultLbl BYTE  "Credits needed for your chosen degree", 13,10
sum     BYTE    11 DUP (?), 0

.CODE
_MainProc PROC
        input   prompt1, stringIn, 80   ;ask for string of student name and degree
        lea     eax, stringIn           ;source
        push    eax
        lea     eax, stringOut
        push    eax
        call    strcopy
        add     esp, 8

        input   prompt2, string, 60
        atod    string
        mov     credits_needed, eax

        input   prompt3, string, 60
        atod    string
        mov     credits_completed, eax

        mov     eax, credits_needed   ; credits needed to EAX
        sub     eax, credits_completed    ; subtract credits earned     
        dtoa    sum, eax        ; convert to ASCII characters       

        output  displayLbl, stringOut
        output  resultLbl, sum  ; output label and sum

        mov     eax, 0  ; exit with return code 0
        ret

    _MainProc ENDP

strcopy PROC NEAR32
        push    ebp
        mov     ebp, esp
        push    edi
        push    esi
        pushfd

        mov     edi, [ebp+8]
        mov esi, [ebp+12]
        cld
whileNoNull:
        cmp     BYTE PTR [esi], 0
        je      endWhileNoNull
        movsb
        jmp     whileNoNull
endWhileNoNull:
        mov     BYTE PTR [edi],0

        popfd
        pop     esi
        pop     edi
        pop     ebp
        ret
strcopy ENDP
END                             ; end of source code

引起我注意的是,如果没有看到io.h资源,就不可能这样说:

.586
EXTRN _getInput:NEAR32, _showOutput:NEAR32, atodproc:NEAR32, dtoaproc:NEAR32, wtoaproc:NEAR32, atowproc:NEAR32


dtoa        MACRO  dest,source         ; convert double to ASCII string
            push   ebx                 ; save EBX
            lea    ebx, dest           ; destination address
            push   ebx                 ; destination parameter
            mov    ebx, [esp+4]        ; in case source was EBX
            mov    ebx, source         ; source value
            push   ebx                 ; source parameter
            call   dtoaproc            ; call dtoaproc(source,dest)
            add    esp, 8              ; remove parameters
            pop    ebx                 ; restore EBX
            ENDM

atod        MACRO  source              ; convert ASCII string to integer in EAX
            lea    eax,source          ; source address to AX
            push   eax                 ; source parameter on stack
            call   atodproc            ; call atodproc(source)
            add    esp, 4              ; remove parameter
            ENDM

wtoa        MACRO  dest,source         ; convert word to ASCII string
            push   ebx                 ; save EBX
            lea    ebx,dest            ; destination address
            push   ebx                 ; destination parameter
            mov    ebx, [esp+4]        ; in case source was BX
            mov    bx, source          ; source value
            push   ebx                 ; source parameter
            call   wtoaproc            ; call dtoaproc(source,dest)
            add    esp, 8              ; remove parameters
            pop    ebx                 ; restore EBX
            ENDM

atow        MACRO  source              ; convert ASCII string to integer in AX
            lea    eax,source          ; source address to AX
            push   eax                 ; source parameter on stack
            call   atowproc            ; call atodproc(source)
            add    esp, 4              ; remove parameter
            ENDM

output      MACRO  outLbl, outStr      ; display label and string

            pushad                     ; save general registers
            cld                        ; clear DF
            lea    eax,outStr          ; string address
            push   eax                 ; string parameter on stack
            lea    eax,outLbl          ; label address
            push   eax                 ; string parameter on stack
            call   _showOutput         ; showOutput(outLbl, outStr)
            add    esp, 8              ; remove parameters
            popad                      ; restore general registers
            ENDM

input       MACRO  inPrompt, inStr, maxLength     ; prompt for and input  string
            pushad                     ; save general registers
            mov    ebx, maxLength      ; length of input string
            push   ebx                 ; length parameter on stack
            lea    ebx,inStr           ; destination address
            push   ebx                 ; dest parameter on stack
            lea    ebx,inPrompt        ; prompt address
            push   ebx                 ; prompt parameter on stack
            call   _getInput           ; getInput(inPrompt, inStr, maxLength)
            add    esp, 12             ; remove parameters
            popad                      ; restore general registers
            ENDM

.NOLISTMACRO ; suppress macro expansion listings
.LIST        ; begin listing

1 个答案:

答案 0 :(得分:1)

  

是否可以将两个框组合成一个显示两组输出的框?

如果您从 stringOut 缓冲区中的 stringIn 中复制输入并同时拥有,则可以轻松地同时显示这两组信息 stringOut 缓冲区附近的resultLbl sum

步骤1,使缓冲区相邻

displayLbl  BYTE  "Student Name - Student Degree...", 0
stringOut   BYTE  80 DUP (?), 10
resultLbl   BYTE  "Credits needed for your chosen degree", 13,10
sum         BYTE  11 DUP (?), 0

请注意 stringOut 之后的额外换行符!

步骤2,在 stringOut 缓冲区

中向上复制
input   prompt1, stringIn, 80   ;ask for string of student name and degree
lea     eax, stringIn           ;source
push    eax
call    szlen                   ;Gives length in EAX
mov     ebx, stringOut+79       ;Position for the terminating zero
sub     ebx, eax                ; minus the length
push    ebx
call    strcopy
add     esp, 8
mov     byte ptr [stringOut+79], 13

...     other stuff that doesn't clobber EBX

这里至关重要的是用回车符替换 strcopy 写的终止零,以便所有文本都能无缝连接。

步骤3,一次显示

output  displayLbl, [ebx]

这是 szlen 宏在 io.h 中定义的方式:

szlen       MACRO  string              ; get string length
            lea    eax, string         ; string address
            push   eax                 ; string parameter on stack
            call   szlenproc           ; call szlenproc(string)
            ENDM

这就是 szlenproc 过程的样子:

; szlenproc(source)
; Procedure to calculate length of a null-terminated string
; No registers are changed; flags are not affected.

szlenproc   PROC   NEAR32
            push   ebp                 ; save base pointer
            mov    ebp, esp            ; establish stack frame
            pushad
            pushfd                     ; save flags

            mov    esi,[ebp+8]         ; source address
            mov    strAddr, esi

; find string length
            mov    strLength, 0        ; initialize string length
WhileChar:  cmp    BYTE PTR [esi], 0   ; character = null?
            jz     EndWhileChar        ; exit if so
            inc    strLength           ; increment character count
            inc    esi                 ; point at next character
            jmp    WhileChar
EndWhileChar:
            popfd                      ; restore flags
            popad                      ; restore registers
            pop    ebp 
            mov    eax, strLength      ; rerun string length in EAX
            ret    4                   ;exit, discarding parameter
szlenproc   ENDP