FASM编写Hello World进行控制台,完全没有包含或依赖项

问题描述

我见过

How to write hello world in assembler under Windows?

Writing hello,world to console in Fasm with DOS

How to write to the console in fasm?

我已经尝试/看到了this answer

这样的MASM示例代码
;---ASM Hello World Win64 MessageBox

extrn MessageBoxA: PROC
extrn ExitProcess: PROC

.data
title db 'Win64',0
msg db 'Hello World!',0

.code
main proc
  sub rsp,28h  
  mov rcx,0       ; hWnd = HWND_DESKTOP
  lea rdx,msg     ; LPCSTR lpText
  lea r8,title   ; LPCSTR lpCaption
  mov r9d,0       ; uType = MB_OK
  call MessageBoxA
  add rsp,28h  
  mov ecx,eax     ; uExitCode = MessageBox(...)
  call ExitProcess
main endp

End

(由于FASM无法理解该MASM指令,因此在Windows 64位extrn MessageBoxA:PROC上出现错误“非法指令”。)

也是该FASM示例from this question

 ; Example of 64-bit PE program


format PE64 GUI 
entry start 

section '.text' code readable executable 

  start: 
      sub     rsp,8*5         ; reserve stack for API use and make stack dqword aligned 

    mov     r9d,0 
    lea     r8,[_caption] 
    lea     rdx,[_message] 
    mov    rcx,0 
    call    [MessageBoxA] 

    mov     ecx,eax 
    call    [ExitProcess] 

section '.data' data readable writeable 

  _caption db 'Win64 assembly program',0 
  _message db 'Hello World!',0 

section '.idata' import data readable writeable 

  dd 0,RVA kernel_name,RVA kernel_table 
  dd 0,RVA user_name,RVA user_table 
  dd 0,0 

  kernel_table: 
    ExitProcess dq RVA _ExitProcess 
    dq 0 
  user_table: 
    MessageBoxA dq RVA _MessageBoxA 
    dq 0 

  kernel_name db 'KERNEL32.DLL',0 
  user_name db 'USER32.DLL',0 

  _ExitProcess dw 0 
    db 'ExitProcess',0 
  _MessageBoxA dw 0 
    db 'MessageBoxA',0

但是它显示一个消息框,并且还具有外部依赖项“ kernel32.dll”和“ user32.dll”

还尝试了此示例from the FASM forum

format pe console


include 'win32ax.inc'

entry main

section '.data!!!' data readable writeable

strHello db 'Hello World !',13,10,0
strPause db 'pause',0

section '.txt' code executable readable

main:
       ; you can use crt functions or windows API.
       cinvoke printf,strHello
       cinvoke system,strPause; or import getc()
       ; or
       ; invoke printf,srtHello
       ; add esp,4

       ; or use WriteFile and GetStdHandle APIs
       push 0
       call [ExitProcess]
      
section '.blah' import data readable

library kernel32,'kernel32.dll',\
    msvcrt,'msvcrt.dll'    ;; C-Run time from MS. This is always on every windows machine

import kernel32,\
          ExitProcess,'ExitProcess'
import msvcrt,\
          printf,'printf',\
          system,'system'

但这取决于win32ax.inc和其他进口

format PE console
include 'win32ax.inc'
.code
start:
        invoke  WriteConsole,<invoke GetStdHandle,STD_OUTPUT_HANDLE>,"Hello World !",0
        invoke  Sleep,-1
.end start

但需要导入“ win32ax.inc”

没有win32ax from the FASM forum,我能找到的最接近的

format pe64 console
entry start

STD_OUTPUT_HANDLE       = -11

section '.text' code readable executable

start:
        sub     rsp,8*7         ; reserve stack for API use and make stack dqword aligned
        mov     rcx,STD_OUTPUT_HANDLE
        call    [GetStdHandle]
        mov     rcx,rax
        lea     rdx,[message]
        mov     r8d,message_length
        lea     r9,[rsp+4*8]
        mov     qword[rsp+4*8],0
        call    [WriteFile]
        mov     ecx,eax
        call    [ExitProcess]

section '.data' data readable writeable

message         db 'Hello World!',0
message_length  = $ - message

section '.idata' import data readable writeable

        dd      0,RVA kernel_table
        dd      0,0

kernel_table:
        ExitProcess     dq RVA _ExitProcess
        GetStdHandle    dq RVA _GetStdHandle
        WriteFile       dq RVA _WriteFile
                        dq 0

kernel_name     db 'KERNEL32.DLL',0
user_name       db 'USER32.DLL',0

_ExitProcess    db 0,'ExitProcess',0
_GetStdHandle   db 0,'GetStdHandle',0
_WriteFile      db 0,'WriteFile',0    

但仍然需要kernel32.dll和user32.dll

有没有完全没有任何外部DLL的方法?我知道程序fasm本身就可以完成,并打印到控制台上,对吗?

解决方法

有没有完全没有任何外部DLL的方法?

在Windows下:绝对不会!

Windows使用某些方法(可能是syscall)进入操作系统,但是,没有正式的入口点。

这意味着(不太可能但)与当前Windows版本中显示"Hello world"消息框的程序完全相同,这在下一次Windows更新之后可能会完全不同!

由于Microsoft假定每个Windows程序仅通过使用与内核版本匹配的.dll文件来调用操作系统,所以他们可以这样做。

我不知道Windows 10,但是较旧的Windows版本(我不记得它是XP,Vista还是7),甚至只是假设.exe文件会立即返回使用任何.dll文件:在这种情况下,程序甚至没有启动!

,

我知道程序fasm本身就可以完成并打印到控制台上

事实并非如此,fasm也在使用kernel32 API。

enter image description here

FWIW kernel32已加载到Windows中每个进程的内存空间中,因此使用kernel32 API不会带来任何代价或开销。

,

您可能喜欢€ASM中的Windows示例,该示例未明确提及任何DLL,并且不需要其他外部库。

只需将源文件保存为“ bluej.asm”,并与euroasm bluej.asm进行链接并以bluej.exe的身份运行。

尽管如此,如果不使用从默认Windows系统库“ kernel32.dll”导入的API函数,您将无法摆脱。

bluej PROGRAM Format=PE,Entry=Start:
        IMPORT GetStdHandle,WriteFile,ExitProcess
Start:  PUSH -11         ; Param 1: standard output handle identificator.
        CALL GetStdHandle; Return StdOutput handle in EAX.
        PUSH 0           ; Param 5: no overlap.
        PUSH Written     ; Param 4: Address of a variable to store number of written bytes.
        PUSH MsgSize     ; Param 3: Number of bytes to write.
        PUSH Msg         ; Param 2: Address of text.
        PUSH EAX         ; Param 1: Output file handle.
        CALL WriteFile   ; System call.
        PUSH 0           ; Errorlevel.
        CALL ExitProcess ; System call.
Written DD 0
Msg     DB "Hello,world!"
MsgSize EQU $ - Msg
      ENDPROGRAM

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...