3

「Hello, world!」を表示しようとしています。最新のアセンブラーが豊富に提供しているように見える松葉杖を使用せずに、64 ビット Windows 7 マシンで FASM を使用します。

私が見つけることができるすべての例とチュートリアルは、事前に作成されたコードを含むマクロに頼るか、高水準言語からライブラリをインポートすることを主張しているため、このかなり単純なタスクは驚くほどイライラすることが判明しました. アセンブリを学びたいと思っている人は、コンピューターがどのように機能するかを直接的かつ詳細に理解するために学ぶのが一般的だと思いました。これらの抽象化と難読化はすべて、その目的を損なうようです。

暴言はさておき、「Hello, world!」を表示できるコードを探しています。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

正直なところ、これを行う極端な理由がない限り、提供されているツール (この場合はリンカー) を使用するのではなく、時間を無駄にすることになります。ループ)。

于 2013-02-04T11:50:18.677 に答える
1
  1. Google に助けを求める: http://board.flatassemblyr.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

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'
于 2020-02-01T06:22:17.163 に答える