Assembly write number to file

2019-08-30 01:19发布

I try to write number to file via Assembler

Include Irvine32.inc

.data

fileName DB 'number.txt',0
FileHandle DD ?
numberBytes DD ?
number DD 101
numberChar DD $-cislo

.code

WriteToFileP proc


;create file
push NULL
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push NULL
push 0
push GENERIC_WRITE
push offset fileName
call CreateFileA
mov FileHandle,eax

;write  
push NULL
push offset numberBytes 
push numberChar
push number
push FileHandle
call WriteFile

; close file    
push FileHandle
call CloseHandle

ret
WriteToFileP ENDP
end

It doesn´t work. I have tried to change push number for push offset number but it doesnt´work too.Any idea how to write number to file?

2条回答
迷人小祖宗
2楼-- · 2019-08-30 01:43

The assembler had converted the decimal "101" in the line number DD 101 to the internal CPU format "dword". WriteFile writes that as a sequence of bytes to the file and an editor would show crap, since it interprets it as a sequence of characters. First the dword has to be converted to a string.

The WinApi contains a function which can be used as conversion routine: wsprintf. Since the Irvine32 library declares this function, it can be used without further circumstances:

Include Irvine32.inc
IncludeLib Irvine32.lib
IncludeLib Kernel32.lib
IncludeLib User32.lib

.data
...
    numberstring db 16 DUP (0)
    numberChar DD 0
    fmt db "%d",0

.code

WriteToFileP proc

    ;create file
    push NULL
    push FILE_ATTRIBUTE_NORMAL
    push CREATE_ALWAYS
    push NULL
    push 0
    push GENERIC_WRITE
    push offset fileName
    call CreateFileA
    mov FileHandle,eax

    ;convert number to string
    push number                     ; Argument for format string
    push offset fmt                 ; Pointer to format string ("%d")
    push offset numberstring        ; Pointer to buffer for output
    call wsprintf                   ; Irvine32.inc / SmallWin.inc / User32.lib / User32.dll
    mov numberChar, eax             ; Length of the stored string
    add esp, (3*4)                  ; CCALL calling function! Adjust the stack.

    ;write
    push NULL
    push offset numberBytes
    push numberChar
    push offset numberstring
    push FileHandle
    call WriteFile

    ; close file
    push FileHandle
    call CloseHandle

    ret
WriteToFileP ENDP
end
查看更多
Emotional °昔
3楼-- · 2019-08-30 02:01

Your code has a couple of problems, it doesn't check for errors, and if you want to write a number in "text format", you need to make it a string, like this: number DB '101',0

Any idea how to write number to file?

You should be able to fix your code, you're almost there. Here's some code I wrote a long time ago if you want to take a look. It's MASM32 asm and makes use of some macros. invoke is just like pushing and calling by hand, but in one line.

; Opens and writes data to a file, will create it if needed
; path must be a valid cstring path
; data and dataSize must describe a readable chunk of memory
; Returns 0 on sucess and -1 on error
WriteFileNohandle proc path:ptr, data:ptr, dataSize:dword
    invoke CreateFile, path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
    cmp eax, INVALID_HANDLE_VALUE
    je openFail
    push ebx
    mov ebx, eax

    sub esp, 4
    mov edx, esp
    invoke WriteFile, ebx, data, dataSize, edx, 0
    add esp, 4
    test eax, eax
    jz fail

ok:
    invoke CloseHandle, ebx
    xor eax,eax

done:
    pop ebx
    ret

fail:
    invoke  CloseHandle, ebx

openFail:
    mov eax, -1
    jmp done
WriteFileNohandle endp
查看更多
登录 后发表回答