3

我正在尝试显示“你好,世界!” 在 64 位 Windows 7 机器上使用 FASM,而无需使用现代汇编程序似乎大量提供的拐杖。

事实证明,这个相当简单的任务令人惊讶地令人沮丧,因为我能找到的每个示例和教程都坚持使用宏,包括预先编写的代码,或从高级语言导入库。我认为想要学习汇编的人通常这样做是为了对计算机的工作原理有一个直接而深入的了解。所有这些抽象和混淆似乎有损于该目的。

除了咆哮,我正在寻找可以显示“你好,世界!”的代码。在控制台上,除了直接访问 Windows API 之外,无需重用、包括和导入任何内容。尽管我知道许多汇编程序都附带提供对 Windows API 的访问的文件,但我宁愿不依赖它们。

此外,如果您对我可以使用哪些汇编程序或教程来更好地促进我的学习方法有任何建议,我将不胜感激。

4

4 回答 4

3

“纯”Windows 编程的一个大问题是 Windows 要求程序包含导入部分,即必须向程序提供来自系统 DLL 的哪些函数——所谓的导入表。

该表不是程序的一部分,与汇编编程本身无关。此外,导入表结构复杂,手动构建不太方便。这就是为什么 FASM 为用户提供了一些标准的方式来构建这些导入表。

如果您的目标是学习汇编,那么正确的方法是阅读 FASM 手册,其中描述了这些宏,然后阅读任何 FASM 发行版中提供的示例代码,然后开始使用它们并专注于汇编编程.

适度使用宏不会让你的程序少写汇编!

FASM 留言板是提出问题和寻求帮助的好地方,但你毕竟必须做功课。

于 2013-02-04T11:07:27.600 回答
2

Windows 下的每个运行进程都会将 kernel32 或 kernalbase 加载到其地址空间中,使用这一事实和 PEB 内部,您可以轻松访问任何 Windows 功能(前提是您具有正确的访问权限)。

博客条目详细介绍了如何执行此操作以显示带有MessageBoxA.

老实说,除非您有一些极端的理由这样做,否则您最终只会浪费时间,而是使用提供的工具(在这种情况下是链接器,因此您可以访问任何 Windows API 而无需经过 10000 个障碍和循环)。

于 2013-02-04T11:50:18.677 回答
1
  1. 向谷歌寻求帮助:http ://board.flatassembler.net/topic.php?t=14034
  2. 自己试试

 ; 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,0,0,RVA kernel_name,RVA kernel_table 
  dd 0,0,0,RVA user_name,RVA user_table 
  dd 0,0,0,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

使用nasm编译从这里获取的这个 hello world(16 位)代码:

.model tiny
.code
org 100h
 
main  proc
 
      mov    ah,9                       ; Display String Service
      mov    dx,offset hello_message    ; Offset of message (Segment DS is the right segment in .COM files)
      int    21h                        ; call DOS int 21h service to display message at ptr ds:dx
 
      retn                              ; returns to address 0000 off the stack 
                                        ; which points to bytes which make int 20h (exit program)
 
hello_message db 'Hello, world!$'
 
main  endp
end   main
于 2013-01-30T08:25:27.730 回答
1

我设法仅链接到一个库 ( kernel32.dll) 并引用了 3 个函数:

GetStdHandle

WriteConsole

ExitProcess

下面的代码是我详尽的谷歌搜索的结果,以及我自己对 MS 文档的参考。

format PE console
entry start

include 'include\win32a.inc'

section '.data' data readable writable
     msg     db 'Hello World!',13,10,0
     len = $-msg
     dummy   dd ?

section '.code' readable writable executable

  start:

push STD_OUTPUT_HANDLE
call [GetStdHandle] ;STD_OUTPUT_HANDLE (DWORD)-11

push 0      ;LPVOID  lpReserved
push dummy  ;LPDWORD lpNumberOfCharsWritten
push len    ;DWORD   nNumberOfCharsToWrite
push msg    ;VOID    *lpBuffer;
push eax    ;HANDLE  hConsoleOutput
call [WriteConsole]

push 0
call [ExitProcess]

section '.idata' data import readable writable

library kernel32,'KERNEL32.DLL' 
include 'include\api\kernel32.inc'
于 2020-02-01T06:22:17.163 回答