Ir para conteúdo

fredericopissarra

Membros
  • Total de itens

    2
  • Registro em

  • Última visita

Reputação

2 Neutral

2 Seguidores

  1. “Hello world” em nasm no Linux x86

    Eu mudaria pouca coisa: Mover valores imediatos para registradores de 32 bits automaticamente zera os 32 bits superiores; Por motivoo de clareza, usar LEA ao invés de MOV para inicializar registradores com ponteiros; Offsets relativos a RIP são menores que os tradicionais; Valores constantes, incluindo strings, deveriam ser colocados em .rodata, não .data. bits 64 section .rodata msg: db "Hello!",10 msg_len equ $ - msg section .text global _start _start: mov eax,1 ; syscall 1: write mov edi,eax ; STDOUT_FILENO lea rsi,[rel msg] ; offsets relativos a RIP são menores. mov edx,msg_len syscall mov eax,60 ; syscall 60: exit xor edi,edi syscall Assim as instruções ficam pequenas (apenas LEA, acima, tem o prefixo REX).
  2. Hello world em MASM no Windows

    Eis porque não gosto muito de criar aplicações diretamente em assembly: Praticamente não há vantagem alguma em fazê-lo. Experimente criar o mesmo programinha em C, compilá-lo e linká-lo extirpando os símbolos desnecessários e faça o mesmo com o seu código com o MASM. É possível que obtenha executáveis com o mesmíssimo tamanho. Outro detalhe é quanto à "versão" do Windows em uso... No Win64 a convenção de chamada é diferente, usando os registradores RCX, RDX, R8 e R9 para os 4 primeiros argumentos de uma chamada, ao invés da pilha (que é o padrao de cdecl e stdcall no modo i386 - ou Win32). Eis um código igual ao acima, para Win64, mas usando o NASM: bits 64 section .rodata msg: db "Hello!",0 caption: db "Hello Windows App",0 section .text ; Importado de user32.dll extern __imp_MessageBoxA global WinMain WinMain: sub rsp,40 ; Isso é necessário. ; Estranhamente é preciso avançar RSP ; por causa dos argumentos de WinMain e ; o endereço de retorno... senão dá crash! xor ecx,ecx ; hWnd = NULL lea rdx,[msg] ; msg ptr lea r8,[caption] ; caption ptr mov r9d,0x40 ; MB_OK | MB_ICONINFORMATION call [__imp_MessageBoxA] xor eax,eax ; return 0L; add rsp,40 ; Retorna a pilha para o lugar original. ret Note que MessageBoxA está sendo chamada indiretamente, via o ponteiro que é inicializado ao importar as bibliotecas libkernel32.a e libuser32.a (que contém código e links para late biding com as respectivas DLLs)... A macro "invoke" faz o que fiz acima (mas, no caso, usei a convenção para Win64). Para compilá-lo, usando o MinGW64 (no Linux), pode-se usar o seguinte Makefile: CC=x86_64-w64-mingw32-gcc hellowin.exe: hellowin.o $(CC) -Wl,--subsystem=windows -s -o $@ $^ -luser32 -lkernel32 hellowin.o: hellowin.asm nasm -fwin64 -o $@ $< Isso ai vai gerar um hellowin.exe com apenas 16 KiB (a mesma coisa que seria gerada com um arquivo em C) e funciona direitinho:
×