如何显示“Hello,world!”没有使用高级汇编程序的好处?

时间:2013-01-30 08:18:55

标签: assembly x86 x86-64

我正试图展示“Hello,world!”在64位Windows 7机器上使用FASM,而不使用现代装配商似乎提供的拐杖。

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

抛开一边,我正在寻找可以显示“Hello,world!”的代码。在控制台上没有重用,包括和导入除直接访问Windows API之外的任何内容。虽然我知道很多汇编程序都附带了提供Windows API访问权限的文件,但我宁愿不依赖它们。

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

4 个答案:

答案 0 :(得分:2)

“纯”Windows编程的一个大问题是Windows要求程序包含导入部分,关于必须向系统提供系统DLL的哪些功能 - 所谓的导入表。

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

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

适度使用宏不会使您的程序编写更少的汇编!

FASM message board是提问和寻求帮助的好地方,但毕竟你必须完成作业。

答案 1 :(得分:1)

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

This博客条目详细说明如何执行此操作以显示MessageBoxA的邮件。

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

答案 2 :(得分:1)

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

GetStdHandle

WriteConsole

ExitProcess

下面的代码是我详尽的Google搜索的结果,也是我对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'

答案 3 :(得分:0)

  1. 使用谷歌:http://board.flatassembler.net/topic.php?t=14034
  2. 尝试自己动手

  3.  ; 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并从惊人的wiki one page编译这个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