简体   繁体   English

x86(MASM)程序集中的“写入文件”过程未显示正确的数据

[英]“writing to a file” procedure in x86 (MASM) assembly not displaying correct data

I have a WriteFileContents procedure that was provided to me from my instructor. 我有一个由老师提供的WriteFileContents过程。 It's suppose to write data to a file, but Chinese characters are being displayed in the text file produced and not the original english text. 假定将数据写入文件,但是在生成的文本文件中显示的是中文字符,而不是原始的英文文本。 Also when I enter data using option 1 then chose to save it to file, nothing is saved in the generated file. 同样,当我使用选项1输入数据然后选择将其保存到文件时,在生成的文件中什么也没有保存。 In this snippet of my program I have 3 operations. 在我的程序的这段代码中,我有3个操作。

  1. to read data from the console and store it 从控制台读取数据并将其存储
  2. to read data from a file and store it 从文件中读取数据并存储
  3. take stored data and write it to a file. 提取存储的数据并将其写入文件。

the data to be written to the file is stored in the variable fdata. 要写入文件的数据存储在变量fdata中。

the key procedures in play are WriteFileContents and Update_fdata I debugged several times and wasn't able to pinpoint the issue. 我正在调试的关键过程是WriteFileContentsUpdate_fdata ,但无法确定问题所在。 I don't know why the text is displaying incorrectly. 我不知道为什么文本显示不正确。


title prog.asm                          ;DOS file name of program

.586                                    ;enable all pentium instructions
.model flat, stdcall                    ;memory model & calling convention
.stack 8192                             ;allocate 8k for stack

INCLUDELIB kernel32.lib                 ;Include the kernel 32 library

;----------------------------------------------------------
; Constant Definitions
;----------------------------------------------------------

MAX_LINE  equ 80
BUF_SIZE equ 240

STD_INPUT  equ -10d                     ;Function number for keyboard input
STD_OUTPUT equ -11d                     ;Function number for monitor output

LF equ 10d                              ;Line feed ascii constant
CR equ 13d                              ;Carriage return constant
NEWLINE equ CR,LF                       ;Combine CR and LF for carriage return

ENABLE_PROCESSED_INPUT  equ 1           ;Flag to turn off line buffering
ENABLE_PROCESSED_OUTPUT equ 1           ;Flag to turn off line bufferin
ENABLE_LINE_WRAP        equ 3           ;Flag to trun line wrap on
DISABLE_PROCESSED_INPUT equ 7           ;Flag to turn on line buffering

CREATE_NEW    EQU  1                    ;Parameter for creating a new file
CREATE_ALWAYS EQU  2                    ;Always create (overwrite existing)
OPEN_EXISTING EQU  3                    ;Parameter for opening an existing file
GENERIC_READ  EQU  80000000h            ;Parameter for reading a file
GENERIC_WRITE EQU  40000000h            ;Parameter for writing a file

FILE_SHARE_READ   equ 1
FILE_SHARE_WRITE  equ 2
FILE_SHARE_DELETE equ 4

FILE_ATTRIBUTE_NORMAL equ 80h
INVALID_HANDLE_VALUE equ 0FFFFFFFFh
HANDLE equ dword

;----------------------------------------------------------
; prototype Declarations for libarary imports
;----------------------------------------------------------

ExitProcess proto,
dwExitCode:dword                   ;The exit code for the process 

GetStdHandle proto, 
nStdHandle: dword                  ;The standard device. -10=INPUT, -11=OUTPUT, -13=ERROR

SetConsoleMode proto,                  
hConsoleHandle:dword,              ;A handle to the console input buffer or a console screen buffer
dwMode:dword                       ;The input or output mode to be set. 

ReadFile proto, 
hFile:dword,                       ;A handle to the device
lpBuffer:near32,                   ;A pointer to the buffer that receives the data read 
nNumberOfCharsToRead:dword,        ;The maximum number of bytes to be read.
lpNumberOfbytesRead:near32,        ;A pointer to the variable that receives the number of bytes read
lpOverlapped:near32                ;A pointer to an OVERLAPPED structure is required if the hFile parameter 
                                   ;was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL.


WriteFile proto,                  
hFile:dword, lpBuffer:near32,      ;A handle to the device
nNumberOfCharsToWrite:dword,       ;The maximum number of bytes to be written.
lpNumberOfbytesWritten:near32,     ;A pointer to the variable that receives the number of bytes written
lpOverlapped:near32                ;A pointer to an OVERLAPPED structure is required if the hFile parameter 
                                   ;was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL.

CloseHandle proto,                     ;Prototype for closing a file
fHandle:dword

GetLastError proto                     ;Prototype for getting specific error

CreateFileA proto,                     ;Prototype for CreateFile, used for getting handle to new or existin file
lpFileName:near32,
dwDesiredAccess:dword,
dwShareMode:dword,
lpSecurityAttributes:near32,
dwCreationDisposition:dword,
dwFlagsAndAttributes:dword,
hTemplateFile:dword

GetConsoleScreenBufferInfo proto,
hConsoleOutput:dword,               ; A handle to the console screen buffer. 
lpConsoleScreenBufferInfo:near32    ; A pointer to a CONSOLE_SCREEN_BUFFER_INFO structure

FillConsoleOutputCharacterA proto,
hConsoleOutput:dword,               ; A handle to the console screen buffer. 
cCharacter:byte,                    ; The character to be written to the console screen buffer.
nLength:dword,                      ; The number of character cells to which the character should be written.
dwWriteCoord:dword,                 ; A COORD structure that specifies the character coordinates of the first cell
lpNumberOfCharsWritten:near32       ; A pointer to a variable that receives the number of characters actually written

SetConsoleCursorPosition proto,
hConsoleOutput:dword,               ; A handle to the console screen buffer. 
dwCursorPosition:dword              ; new cursor position,




;----------------------------------------------------------
; Data Segment -- Global Variables
;----------------------------------------------------------

.data
strAddr         dd  ?
strLength       dd  ?
hStdOut         dd  ?
hStdIn          dd  ?
hFileOut        dd  ?
hFileIn         dd  ?
read            dd  ?
written         dd  ?   
coord           dd  0
scrnBufInfo     db 22 DUP(0)
inFilename      db 256 dup(0)
outFilename     db 256 dup(0)
fdata           db BUF_SIZE dup(0)
numBytes        dd ?

newlineStr      db NEWLINE, 0       ;string for printing newline
filePrompt      db "Enter filename: ",0
mnuItem1        db "1) Enter new line",NEWLINE,0
mnuItem2        db "2) Read from file",NEWLINE,0
mnuItem3        db "3) Save to File",NEWLINE,0
mnuItem4        db "4) Exit",NEWLINE,0
mnuPrompt       db ": ",0
invalidOption   db "Invalid Option! ",0
continuePrompt  db "Press enter key to continue...",NEWLINE,0
fileError       db "Error reading file!",NEWLINE,0
goodbyeMsg      db "Goodbye.", NEWLINE, 0
enterDataMsg    db "Enter data:",NEWLINE,0
enterOutfilename     db "Enter a name for file:",NEWLINE,0
newData         db BUF_SIZE dup(0)
sectNum1        word 0              ;for holding the section number entered by user 
sectNum2        word 0              ;for holding the section number entered by user 
outData         db BUF_SIZE dup(0)  ; the finished string to be displayed
tempData        db BUF_SIZE dup(0)  ; extra string for temperary holding
sepStr          db "-------------------------------------", NEWLINE, 0
zeroStr         db "0", 0
spaceStr        db " ",0
hexStr          db "0x", 0

input1          db 80d dup(0)       ;buffer for user input
output1         db 80d dup(0)       ;buffer for output strings

console_buffer_info db 22 dup(0)
topLeft dword 0


;----------------------------------------------------------
; Code Segment
;----------------------------------------------------------

.code
main proc

MainLoop:

    ; zero out registers
    xor eax, eax                    ; zero out eax
    xor ebx, ebx                    ; zero out ebx
    xor ecx, ecx                    ; zero out ecx
    xor edx, edx                    ; zero out edx


    lea esi, newlineStr 
    call PrintString

    lea esi, sepStr
    call PrintString

    call DisplayMenu

    ; get Menu Option
    lea edi, input1
    call GetString

    cmp input1, '1'
    je option1

    cmp input1, '2'
    je option2

    cmp input1, '3'
    je option3

    cmp input1, '4'
    je Exit

    ; invalid option entered
    lea esi, invalidOption
    call PrintString
    call PauseForEnter

    jmp MainLoop

option1:

    ;display enter data prompt
    lea esi, enterDataMsg
    call PrintString

    ;get data from stdin
    lea edi, outData 
    call GetString

    ;copy outData back to fdata
    call Update_fdata

    ;clear display and display data at top 
    call ClearScreen
    lea esi, fdata
    call PrintString
    jmp MainLoop


option2:

    ; prompt for filename to read
    lea esi, filePrompt
    call PrintString

    ; read filename from console
    lea edi, inFilename
    call GetString

    ; read file data
    call ReadFileContents

    ;clear display and display data at top 
    call ClearScreen
    lea esi, fdata
    call PrintString
    jmp MainLoop



option3:

    ;prompt to enter outFile name
    lea esi, enterOutfilename
    call PrintString

    ;get the outFile name
    lea edi, outFilename
    call GetString

    ;copy outData back to fdata
    call Update_fdata

    ;call WriteFileContents to save file
    call WriteFileContents

    ;clear display and display data at top 
    call ClearScreen
    lea esi, fdata
    call PrintString
    jmp MainLoop


Exit:

    lea esi, goodbyeMsg
    call PrintString


    invoke ExitProcess, 0           ;exit process with no error

main endp


;------------------------------------------------------------------------------
; Procedure to copy outData into fdata
;------------------------------------------------------------------------------
Update_fdata  proc                ; Define procedure
        pushad                     ; save all registers
        pushfd                     ; save flags

        lea esi, outData
        lea edi, fdata

        ;Copy Section
        Update_fdata_loop1:
            cmp byte ptr [esi], 0
            je done_Update_fdata

            mov al, [esi]
            mov [edi], al
            inc esi
            inc edi 

        jmp Update_fdata_loop1
        ;;;;;;;;;;;;;;;;;;;

        done_Update_fdata:
        mov al, 0
        mov [edi], al       ;end EDI with null terminator


        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller
Update_fdata   endp




;------------------------------------------------------------------------------
; Procedure to clear the screen
;------------------------------------------------------------------------------
ClearScreen proc
        pushad                     ; save all registers
        pushfd                     ; save flags

        ; HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
        invoke GetStdHandle,STD_OUTPUT ; get handle for console output
        mov    hStdOut, eax        ; copy file handle for screen

        ; GetConsoleScreenBufferInfo(console, &screen);
        invoke GetConsoleScreenBufferInfo,hStdOut,near32 ptr console_buffer_info

        ; FillConsoleOutputCharacterA(console, ' ', screen.dwSize.X * screen.dwSize.Y, topLeft, &written);
        xor eax, eax
        xor ebx, ebx
        mov ax, word ptr console_buffer_info
        mov bx, word ptr console_buffer_info+2
        mul bx
        invoke FillConsoleOutputCharacterA,hStdOut,' ',eax,topLeft,near32 ptr written

        ; SetConsoleCursorPosition(console, topLeft);
        invoke SetConsoleCursorPosition,hStdOut,topLeft

        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller
ClearScreen endp


;------------------------------------------------------------------------------
; Procedure to display the menu
;------------------------------------------------------------------------------
DisplayMenu proc

lea esi, sepStr
call PrintString

; Option 1: enter new line
lea esi, mnuItem1
call PrintString

; Option 2: save to file
lea esi, mnuItem2
call PrintString

; Option 3: Exit
lea esi, mnuItem3
call PrintString

; Option 4: Exit
lea esi, mnuItem4
call PrintString

lea esi, mnuPrompt
call PrintString


        ret                        ; return to caller
DisplayMenu endp

;------------------------------------------------------------------------------
; Procedure to read file
; [IN] inFilename
; [OUT] file contents in fdata
;------------------------------------------------------------------------------
ReadFileContents  proc                 ; Define procedure
        pushad                     ; save all registers
        pushfd                     ; save flags

        ; zero buffer out
        lea edi, fdata             ; point edi at buffer to be zero'd out
        xor eax, eax               ; put zero into accumulator to write to buffer
        mov cx, BUF_SIZE           ; put buf size into counter
        rep stosb                  ; now fill buffer

        ; open file for reading
        invoke CreateFileA, near32 ptr inFilename, GENERIC_READ, FILE_SHARE_READ,
           0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
        mov hFileIn, eax           ; save file handle

        ; see if we got an error opening file
        cmp eax, INVALID_HANDLE_VALUE
        je error_ReadFileContents

        mov ecx, BUF_SIZE          ; string length
        lea edi, fdata             ; load address of fdata into edi

        invoke ReadFile,           ; invoke standard ReadFile with
          eax,                     ;   file handle for keyboard
          edi,                     ;   address of location to write file contents
          ecx,                     ;   length of string
          near32 ptr read,         ;   variable for # bytes read
          0                        ;   overlapped mode

        invoke CloseHandle, hFileIn; close file handle

        ; display # bytes read
        mov eax, read               ; move num bytes read into eax, so we can save to variable
        mov numBytes, eax           ; now save value from eax into permanent variable
        ;lea esi, read              ; point esi at num bytes read for converting to string
        ;mov ebx, 10                ; set our number base to base 10
        ;lea edi, output1           ; point edit at location to store string
        ;call Num2Str               ; now convert number to a string
        ;mov esi, edi               ; now point esi at that string to display
        ;call PrintString           ; display the string
        ;lea esi, bytesReadStr      ; point esi at " bytes read." string
        ;call PrintString           ; display it
        jmp done_ReadFileContents  ; jump over error handling section

error_ReadFileContents:
        lea esi, fileError         ; point esi at file read error message
        call PrintString           ; now display the message

done_ReadFileContents:
        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller
ReadFileContents   endp

;------------------------------------------------------------------------------
; Procedure to write data to file
; [IN] file contents in fdata
; [IN] outFilename
;------------------------------------------------------------------------------
WriteFileContents  proc                ; Define procedure
        pushad                     ; save all registers
        pushfd                     ; save flags

        invoke CreateFileA, near32 ptr outFilename, GENERIC_WRITE, FILE_SHARE_WRITE,
           0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
        mov hFileOut, eax

        lea esi, fdata
        invoke WriteFile,          ; invoke standard WriteFile with
          hFileOut,                ;   file handle for screen
          esi,                     ;   address of string
          numBytes,                ;   length of string
          near32 ptr written,      ;   variable for # bytes written
          0                        ;   overlapped mode          

        invoke CloseHandle, hFileOut; close file handle

        ; display number of bytes written
        ;lea esi, numBytes          ; point esi at num bytes read for converting to string
        ;mov ebx, 10                ; set our number base to base 10
        ;lea edi, output1           ; point edit at location to store string
        ;call Num2Str              ; now convert number to a string
        ;mov esi, edi               ; now point esi at that string to display
        ;call PrintString           ; display the string
        ;lea esi, bytesWriteStr     ; point esi at " bytes written." string
        ;call PrintString           ; display it

        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller
WriteFileContents   endp

;------------------------------------------------------------------------------
; Procedure to prompt user to press enter to continue
;------------------------------------------------------------------------------
PauseForEnter proc
        lea esi, continuePrompt    ; point esi at string to prompt user to continue
        call PrintString           ; display prompt
        lea esi, input1            ; point esi at location for user input
        call GetString             ; get user input from console
        ret                        ; return to caller
PauseForEnter endp

;------------------------------------------------------------------------------
; Procedure to print a string to stdout
;
; Given   :  The Address of Null (0) terminated String to print in ESI register
; process :  Print the String using the kernel32.lib WriteFile to
;         :  Standard_Output function call.  No registers are changed and the
;         :  flags are not affected.
; Return  :  Nothing
;------------------------------------------------------------------------------
PrintString proc                       ; Define procedure
        pushad                     ; save registers
        pushfd                     ; save flags
        mov    strAddr, esi        ; copy string address
                                   ; 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           ; while more characters exist
EndWhileChar:
        invoke GetStdHandle,STD_OUTPUT ; get handle for console output
        mov    hStdOut, eax        ; copy file handle for screen
        invoke WriteFile,          ; invoke standard WriteFile with
          hStdOut,                 ;   file handle for screen
          strAddr,                 ;   address of string
          strLength,               ;   length of string
          near32 ptr written,      ;   variable for # bytes written
          0                        ;   overlapped mode
        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller
PrintString endp




;------------------------------------------------------------------------------
; Procedure to get a string from stdin
;
; Given   :  The Address of the String to fill in EDI register
; process :  Input the String using the kernel32.lib ReadFile from the
;         :  Standard_Input function call.  No registers are changed and the
;         :  flags are not affected.
; Return  :  The input string in the data segment
;------------------------------------------------------------------------------
GetString proc                         ; Define procedure
        pushad                     ; save all registers
        pushfd                     ; save flags

        invoke GetStdHandle,STD_INPUT  ; get handle for console
        mov    hStdIn, eax         ; save the handle
        invoke SetConsoleMode,     ; invoke standard console with
          hStdIn,                  ;   file handle for keyboard
          DISABLE_PROCESSED_INPUT  ;   turn line buffering on

        mov    ecx, 255d;MAXSTR    ; string length
        mov    strLength, ecx      ; maximum string to accept
        mov    strAddr, edi        ; save pointer to input string
        invoke ReadFile,           ; invoke standard ReadFile with
          hStdIn,                  ;   file handle for keyboard
          strAddr,                 ;   address of string
          strLength,               ;   length of string
          near32 ptr read,         ;   variable for # bytes read
          0                        ;   overlapped mode

        mov ecx, read            
        mov byte ptr [edi+ecx-2],0 ; replace CR/LF by trailing null

        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller
GetString   endp



;------------------------------------------------------------------------------
; Procedure to print a character to the console
;
; Given   :  The Address of the Character to print in ESI register
; Process :  Print the Character using the kernel32.lib WriteFile to
;         :  Standard_Output function call.  No registers are changed and the
;         :  flags are not affected.
; Return  :  Nothing
;------------------------------------------------------------------------------
PutChar PROC NEAR32                         ; Define procedure
        pushad                          ; save registers
        pushfd                          ; save flags
        INVOKE GetStdHandle,STD_OUTPUT  ; get handle for console output
        mov hStdOut, eax                ; copy file handle for screen
    INVOKE SetConsoleMode,          ; invoke standard console with
        hStdOut,                        ;   file handle for screen
        ENABLE_PROCESSED_OUTPUT     ;   turn line buffering off
    INVOKE WriteFile,               ; invoke standard WriteFile with
        hStdOut,                        ;   file handle for screen
        esi,                            ;   address of character
        1,                              ;   length of one byte
        NEAR32 PTR written,             ;   variable for # bytes written
        0                               ;   overlapped mode
        popfd                           ; restore flags
        popad                           ; restore registers
        ret                             ; return to caller
PutChar ENDP



;------------------------------------------------------------------------------
; Procedure to get a character from the console
;
; Given   :  The Address of the Character to get in ESI register
; Process :  Input the Character using the kernel32.lib ReadFile from the
;         :  Standard_Input function call.  No registers are changed and the
;         :  flags are not affected.
; Return  :  The input character in the data segment
;------------------------------------------------------------------------------
GetChar PROC NEAR32                         ; Define procedure
        pushad                          ; save all registers
        pushfd                          ; save flags
        INVOKE GetStdHandle,STD_INPUT   ; get handle for keyboard
        mov hStdIn, eax                 ; save the handle
        INVOKE SetConsoleMode,          ; invoke standard console with
        hStdIn,                         ;   file handle for keyboard
        ENABLE_PROCESSED_INPUT          ;   turn line buffering off
        INVOKE ReadFile,                ; invoke standard ReadFile with
          hStdIn,                       ;   file handle for keyboard
          esi,                          ;   address of character
          1,                            ;   length of one byte
          NEAR32 PTR read,              ;   variable for # bytes read
          0                             ;   overlapped mode
        call PutChar                    ; echo the character on screen
        popfd                           ; restore flags
        popad                           ; restore registers
        ret                             ; return to caller
GetChar   ENDP

;------------------------------------------------------------------------------
; Procedure to convert a null terminated string into a word-sized unsigned number
;
;  Inputs: ESI points to null terminated string to convert
;          EDI points to location to store answer
;          BX contains number base of given number
;  Outputs: unsigned word stored in location that EDI points to
;------------------------------------------------------------------------------
Str2Num proc
        pushad                     ; save registers
        pushfd                     ; save flags

        ; initialize total to 0
        xor eax, eax                ; using accumulator for total
        xor ecx, ecx                ; zero out all of ecx

        ; loop through each character in string
        charLoop_str2num:

            ; if null terminator, exit loop
            cmp byte ptr [esi], 0
            je done_str2num

            ; if space terminator, exit loop
            cmp byte ptr [esi], ' '
            je done_str2num

            ; if not null, process
            ; weighted positional notation

            ; multiply total times base
            ; dx:ax = ax * bx
            mul bx

            ; convert digit to number and add to total
            mov cl, [esi]           ; move ascii character into register

            cmp cl, '9'             ; see if character is numeric digit
            jg isAlpha_str2num

            ; else, fall through... treat as numeric digit
        isNumeric_str2num:

            sub cl, '0'             ; converting character to number, ie. '1' => 1
            jmp addNumberToTotal

        isAlpha_str2num:

            ; make characters uppercase
            and cl, 0dfh            ; AND with 1101 1111 to turn off bit

            sub cl, 'A'             ; 'A'=0, 'B'=1, 'C'=2, ... 
            add cl, 10              ; 'A'=10, 'B'=11, 'C'=12, ...

        addNumberToTotal:

            add ax, cx              ; add number to total

            ;  increment pointer to next character
            inc esi

            ; continue with loop
            jmp charLoop_str2num

        done_str2num:

            ; number is in AX... let's store answer
            mov [edi], ax               

        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller
Str2Num endp

;------------------------------------------------------------------------------
; Procedure to convert a word-sized unsigned number into a null terminated string
;
;  Inputs: ESI points to unigned word-size integer to convert
;          EDI point to location to store null terminated string
;          BX contains number base of desired output string
;  Outputs: unsigned word stored in location that EDI points to
;------------------------------------------------------------------------------
Num2Str proc
        pushad                     ; save registers
        pushfd                     ; save flags

        mov ax, [esi]           ; move number into accumulator for divide remainder technique
        pushw 0                 ; push null terminator onto stack to mark position

        ; loop until zero
    divLoop:
        xor dx, dx                      ; prep dx register for divide
        div bx                  ; divide ax/bx

        ; remainder can be 0-9... or 10+
        cmp dx, 9
        jg alpha_num2str

        digit_num2str:
            add dx, '0'             ; convert number to ascii character, ie. 7=>'7'
            jmp push_num2str

        alpha_num2str:
            sub dl, 10              ; 10=>0, 11=>1, 12=>2, ...
            add dl, 'A'             ; 0=>A, 1=>B, 2=>C, ...

        push_num2str:
            push dx                 ; save character onto stack
            cmp ax, 0               ; if accum is zero... done with div remainder loop
            jne divLoop             ; if AX != 0... continue with divide remainder

    popCharacters:
        pop dx                  ; pop character off stack
        mov [edi], dl           ; store character onto string
        inc edi                 ; move pointer to next byte
        cmp dl, 0               ; check if null terminator
        jne popCharacters       ; if not null terminator, continue processing characters

    done_num2str:
        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller
Num2Str endp



end  ; end directive to compiler

Using the 32-bit registers instead of the 8-bit registers in the Update_fdata procedure solved my problem with the Chinese characters showing in my created txt files. 在Update_fdata过程中使用32位寄存器而不是8位寄存器解决了我的问题,因为在创建的txt文件中显示了中文字符。

     ;----------------------------------------------------------------------
     ; Procedure to copy outData into fdata
     ;----------------------------------------------------------------------
     Update_fdata  proc           ; Define procedure
        pushad                     ; save all registers
        pushfd                     ; save flags

        xor ecx, ecx
        lea esi, outData
        lea edi, fdata

        ;Copy Section
        Update_fdata_loop1:
            cmp byte ptr [esi], 0
            je done_Update_fdata

            mov eax, [esi]
            mov [edi], eax
            inc esi
            inc edi
            inc ecx 

        jmp Update_fdata_loop1
        ;;;;;;;;;;;;;;;;;;;

        done_Update_fdata:
        mov eax, 0
        mov [edi+1], eax        ;end EDI with null terminator
        inc ecx
        mov numBytes, ecx           ; now save value from eax into permanent variable


        popfd                      ; restore flags
        popad                      ; restore registers
        ret                        ; return to caller

   Update_fdata   endp



As @Michael Petch pointed out numBytes wasn't getting updated whenever I was copying over bytes in the Update_fdata procedure. 正如@Michael Petch指出的,每当我在Update_fdata过程中复制字节时,numBytes都不会更新。 This caused WriteFileContents unable to produce output to the out file. 这导致WriteFileContents无法产生输出到out文件。 Using ECX as a counter and moving the value into numbytes at the end of the Update_fdata procedure corrected this issue. 使用ECX作为计数器,并在Update_fdata过程结束时将其值移动到numbytes中,可以解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM