Como escrever "hello world" em montador debaixo das janelas?

Queria escrever algo básico na montagem debaixo das janelas, estou a usar NASM, mas não consigo Pôr nada a funcionar.

Como Escrever e compilar hello world sem a ajuda de funções C no Windows?

Author: Blechdose, 2009-06-21

8 answers

Exemplos NASM.

Chamando a libc stdio printf, implementando int main(){ return printf(message); }
; ----------------------------------------------------------------------------
; helloworld.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits.  It needs to be linked with a C library.
; ----------------------------------------------------------------------------

    global  _main
    extern  _printf

    section .text
_main:
    push    message
    call    _printf
    add     esp, 4
    ret
message:
    db  'Hello, World', 10, 0

Então corre

nasm -fwin32 helloworld.asm
gcc helloworld.obj
a

Há também O Guia ignorante de Newbies para Hello World em Nasm sem o uso de uma biblioteca C. Então o código ficaria assim.

16-código de bits com chamadas do sistema MS-DOS: funciona em em emuladores DOS ou em janelas de 32 bits com suporte a NTVDM. Não pode ser executado " diretamente "(transparente) sob qualquer Windows de 64 bits, porque um o kernel x86-64 não pode usar o modo vm86.

org 100h
mov dx,msg
mov ah,9
int 21h
mov ah,4Ch
int 21h
msg db 'Hello, World!',0Dh,0Ah,'$'

Construa isto num executável .com para que seja carregado em cs:100h com todos os registos de segmentos iguais um ao outro (modelo de memória minúsculo).

Boa sorte.
 27
Author: anderstornvig, 2018-05-01 23:23:43

Este exemplo mostra como ir diretamente para a API do Windows e não ligar na Biblioteca Padrão do C.

    global _main
    extern  _GetStdHandle@4
    extern  _WriteFile@20
    extern  _ExitProcess@4

    section .text
_main:
    ; DWORD  bytes;    
    mov     ebp, esp
    sub     esp, 4

    ; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE)
    push    -11
    call    _GetStdHandle@4
    mov     ebx, eax    

    ; WriteFile( hstdOut, message, length(message), &bytes, 0);
    push    0
    lea     eax, [ebp-4]
    push    eax
    push    (message_end - message)
    push    message
    push    ebx
    call    _WriteFile@20

    ; ExitProcess(0)
    push    0
    call    _ExitProcess@4

    ; never here
    hlt
message:
    db      'Hello, World', 10
message_end:
Para compilar, vai precisar do NASM e do LINK.EXE (from Visual studio Standard Edition)
   nasm -fwin32 hello.asm
   link /subsystem:console /nodefaultlib /entry:main hello.obj 
 110
Author: caffiend, 2009-06-22 19:51:29

Estes são exemplos Win32 e Win64 usando chamadas da API do Windows. Eles são para MASM em vez de NASM, mas dê uma olhada neles. Você pode encontrar mais detalhes em este artigo.

;---ASM Hello World Win32 MessageBox

.386
.model flat, stdcall
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib

.data
title db 'Win32', 0
msg db 'Hello World', 0

.code

Main:
push 0            ; uType = MB_OK
push offset title ; LPCSTR lpCaption
push offset msg   ; LPCSTR lpText
push 0            ; hWnd = HWND_DESKTOP
call MessageBoxA
push eax          ; uExitCode = MessageBox(...)
call ExitProcess

End Main

;---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

Para montar e ligar estes usando MASM, use isto para um executável de 32 bits:

ml.exe [filename] /link /subsystem:windows 
/defaultlib:kernel32.lib /defaultlib:user32.lib /entry:Main

Ou isto para um executável de 64 bits:

ml64.exe [filename] /link /subsystem:windows 
/defaultlib:kernel32.lib /defaultlib:user32.lib /entry:main
 16
Author: PhiS, 2016-05-25 21:40:10

Assembler Plano não precisa de um linker extra. Isso torna a programação do assembler bastante fácil. Ele também está disponível para Linux.

Isto é hello.asm dos exemplos Fasm:

include 'win32ax.inc'

.code

  start:
    invoke  MessageBox,HWND_DESKTOP,"Hi! I'm the example program!",invoke GetCommandLine,MB_OK
    invoke  ExitProcess,0

.end start

Fasm cria um executável:

>fasm hello.asm
flat assembler  version 1.70.03  (1048575 kilobytes memory)
4 passes, 1536 bytes.
E este é o programa da IDA.:

enter image description here

Podes ver as três chamadas.: GetCommandLine, MessageBox e ExitProcess
 13
Author: ceving, 2013-11-17 15:54:11
Para conseguir um .exe with NASM'compiler and Visual Studio's linker this code works fine:
global WinMain
extern ExitProcess  ; external functions in system libraries 
extern MessageBoxA

section .data 
title:  db 'Win64', 0
msg:    db 'Hello world!', 0

section .text
WinMain:
    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
    call ExitProcess

    hlt     ; never here

Se este código for salvo em, por exemplo, " test64.asm", então para compilar:

nasm -f win64 test64.asm

Produz " test64.obj" Então para ligar a partir da linha de comandos:

path_to_link\link.exe test64.obj /subsystem:windows /entry:WinMain  /libpath:path_to_libs /nodefaultlib kernel32.lib user32.lib /largeaddressaware:no

Where path_to_link could be C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin ou onde quer que esteja a sua ligação.programa exe na sua máquina, o path_ to_libs pode ser C:\Program ficheiros (x86)\Windows Kits\8.1\Lib\winv6.3\um\x64 ou onde quer que estejam as suas bibliotecas (neste caso, ambos os kernel32.lib e user32.lib estão no mesmo lugar, caso contrário, use uma opção para cada caminho que você precisa) e /largeaddressaware:não opção é necessária para evitar a vinculador se queixam de endereços (por user32.lib neste caso). Além disso, como é feito aqui, se linker do Visual é invocado a partir do comando prompt, é necessário configurar o ambiente anteriormente (execute uma vez vcvarsall.morcego e / ou ver MS C++ 2010 e mspdb100.dll ).

 7
Author: rarias, 2017-05-23 12:26:32

A menos que chames alguma função isto não é nada trivial. (E, a sério, não há nenhuma diferença real na complexidade entre chamar printf e chamar uma função API win32.)

Mesmo DOS int 21h é realmente apenas uma chamada de função, mesmo que seja uma API diferente.

Se quiser fazê-lo sem ajuda, precisa de falar directamente com o seu hardware de vídeo, provavelmente escrevendo bitmaps das letras de "Hello world" num framebuffer. Mesmo assim, o cartão de vídeo está fazendo o trabalho de traduzir esses valores de memória em sinais VGA / DVI.

Note que, na verdade, nenhuma destas coisas até ao hardware é mais interessante na ASM do que em C. UM programa "hello world" resume-se a uma chamada de função. Uma coisa boa sobre a ASM é que você pode usar qualquer ABI que você quer razoavelmente fácil; você só precisa saber o que essa ABI é.

 4
Author: Captain Segfault, 2009-06-22 20:34:28
Se quiser usar o linker da NASM e da Visual Studio (link.exe) com o exemplo Hello World de anderstornvig, você terá que se conectar manualmente com o Libário de tempo de execução C que contém a função printf ().
nasm -fwin32 helloworld.asm
link.exe helloworld.obj libcmt.lib
Espero que isto ajude alguém.
 4
Author: tboerman, 2011-02-26 21:54:17

Os melhores exemplos são aqueles com fasm, porque fasm não usa um linker, que esconde a complexidade da programação do windows por outra camada opaca de complexidade. Se você está satisfeito com um programa que escreve em uma janela de gui, então há um exemplo para isso no diretório de exemplo de fasm.

Se você quer um programa de console, que permite redirecionamento do padrão dentro e fora padrão que também é possível. Há um programa de exemplo (helas altamente não-trivial) disponível que não usa um gui, e trabalha estritamente com o console, que é o próprio fasm. Isto pode ser reduzido ao essencial. (Eu escrevi um compilador forth que é outro exemplo não-gui, mas também não-trivial).

Tal programa tem o seguinte comando para gerar um cabeçalho executável adequado, normalmente feito por um linker.

FORMAT PE CONSOLE 

Uma secção chamada'.o idata ' contém uma tabela que ajuda o windows durante o arranque para alguns nomes de funções para os endereços de execução. Também contém uma referência ao KERNEL.DLL que é o Sistema Operacional Windows.

 section '.idata' import data readable writeable
    dd 0,0,0,rva kernel_name,rva kernel_table
    dd 0,0,0,0,0

  kernel_table:
    _ExitProcess@4    DD rva _ExitProcess
    CreateFile        DD rva _CreateFileA
        ...
        ...
    _GetStdHandle@4   DD rva _GetStdHandle
                      DD 0

O formato da tabela é imposto pelo windows e contém Nomes que são pesquisados em arquivos do sistema, quando o programa é iniciado. FASM esconde alguns dos complexidade por trás da palavra-chave rva. Então _ExitProcess@4 é uma etiqueta fasm e _exitProcess é uma cadeia que é observada pelo Windows.

O seu programa está na secção'.texto". Se declarar que essa secção pode ser escrita e executável, é a única secção tens de acrescentar.

    section '.text' code executable readable writable
Pode ligar para todas as instalações que declarou .secção idata. Para um programa de consola, você precisa de _GetStdHandle para encontrar o ficheiro filedescriptors para o standard in and standardout (usando nomes simbólicos como o STD_ INPUT_ handle que o fasm encontra no ficheiro include win32a.inc). Uma vez que você tem os descritores de arquivo você pode fazer WriteFile e ReadFile. Todas as funções são descritas na documentação kernel32. Você provavelmente está ciente disso ou você não tentaria montagem programacao.

Em resumo: existe uma tabela com nomes asci que se juntam ao Sistema Operacional windows. Durante a inicialização isto é transformado em uma tabela de endereços ligáveis, que você usa em seu programa.

 4
Author: Albert van der Horst, 2018-05-15 14:27:52