Author Topic: Help with Hello World and NASM on mingw64  (Read 28758 times)

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Help with Hello World and NASM on mingw64
« Reply #30 on: January 09, 2023, 03:40:02 PM »
Here's how to do it:
Code: [Select]
; test.asm
;
;   nasm -fwin32 -o test.obj test.asm
;   link test.obj /debug:none /release /subsystem:console msvcrt.lib legacy_stdio_definitions.lib
;

  bits  32

  section .rodata

str:
  db  `Hello\n`,0

  section .text

  ; Older MSVCRT exports _cprintf, but you must link with legacy_stdio_definitions.lib.
  extern __cprintf

  global _main

  align 4
_main:
  push  str
  call  __cprintf
  add   esp,4
  ret
Now, take a look at:
Code: [Select]
C:\Work> dumpbin /disasm test.exe3308 bytes in .text, 512 bytes in .data, 2704 bytes in .rodata and 344 in relocations in a simple 'Hello world' program. And lots of code!

Now, this one, to mimic your previous code (with CORRECTIONS):
Code: [Select]
; test.asm
;
; Better approach WITHOUT using libc!
; Why better? Because this code don't need to load MSVCRT???.DLL and all C initialization code.
;
; Unfortunately Windows Console applications must use Console API from kernel32.dll.
;
;   nasm -fwin32 hello.asm -o hello.o
;
;   if using Visual Studio:
;     link hello.o /debug:none /release /subsystem:console /defaultlib:kernel32.lib /entry:start
;   or, with mingw32:
;     ld -s -o hello.exe hello.o -lkernel32
;
; They will create the same image...
;

  ; Yep, it is the default, but I like to be explicit.
  bits  32

  ; Handle put in .bss not to occupy space in the image.
  section .bss

handle:
  resd  1

  ; Notice these buffers won't be changed!
  section .rodata

; Little test: Will change '-' to `\r\n` on terminal.
str:
  db  `Hello-World-`
str_len equ $ - str

crlf:
  db  `\r\n`
crlf_len equ $ - crlf

  section .text

  ; As defined in Win32 Console API.
  %define STD_OUTPUT_HANDLE -11

  extern __imp__GetStdHandle@4
  extern __imp__WriteConsoleA@20
  extern __imp__ExitProcess@4

  global _start

  align 4         ; always a good ideia to align entrypoints.
_start:
  %ifdef OBEY_ABI
    push  ebx       ; Obey MS-ABI and preserve EBX and EDI!
    push  edi       ; Not really necessary here!
  %endif

  ; Gets STDOUT_HANDLE from Console API.
  push  byte STD_OUTPUT_HANDLE
  call  [__imp__GetStdHandle@4]
  mov   [handle],eax
 
  ; prepare to scan the string searching for '-' in the loop below.
  lea   edi,[str]
  mov   ecx,str_len

  align 4             ; always a good idea to align LOOPs entrypoints.
.loop:
  mov   al,'-'
  mov   ebx,edi       ; keep track of the substring start
  repne scasb
  jne   .exit         ; Not found, exit the loop.

  call  print_substring
  call  print_crlf
  jmp   .loop
.exit:

  ; --- Exit from program
  %ifdef OBEY_ABI
    pop   edi           ; Restore EBX and EDI.
    pop   ebx           ; Not really necessary here!
  %endif

  ; Don't need to close the stdout handle!

  ; Must exit jumping to ExitProceess!
  push  byte 0
  jmp   [__imp__ExitProcess@4]

; Prints the substring not including the '-' found.
; Entry: EBX = start of substring,
;        EDI = one char past the '-' found.
; Destroys EAX (at least).
; Preserve ECX to continue scanning.
  align 4
print_substring:
  push  ecx

  lea   eax,[edi-1]
  sub   eax,ebx
  jz    .exit

  push  byte 0
  push  byte 0
  push  eax
  push  ebx
  push  dword [handle]
  call  [__imp__WriteConsoleA@20] ; Since ABI allows changes no ECX it was preserved earlier.
.exit:
  pop   ecx
  ret

; Just print CRLF. Preserve ECX to conitnue scanning.
  align 4
print_crlf:
  push  ecx
 
  push  byte 0
  push  byte 0
  push  crlf_len
  push  crlf
  push  dword [handle]
  call  [__imp__WriteConsoleA@20] ; Since ABI allows changes no ECX it was preserved earlier.

  pop   ecx
  ret
124 bytes in .text, 0 bytes in .data, 4 bytes in .bss, 14 bytes in .rodata, 28 bytes in relocations (7 relocations), and 94 bytes in imported ptrs (from kernel32.dll)...
Code: [Select]
C:\Work> dir *.exe
 Volume in drive C is OS
 Volume Serial Number is 9E55-4C71

 Directory of C:\Work

09/01/2023  12:03             3.072 test.exe
09/01/2023  12:31             9.216 test2.exe
Again, 6 KiB of unecessary code and data to initialize libc... blagh!

« Last Edit: January 09, 2023, 03:43:57 PM by fredericopissarra »

Offline alCoPaUL

  • Jr. Member
  • *
  • Posts: 74
  • Country: ph
    • Webpage
Re: Help with Hello World and NASM on mingw64
« Reply #31 on: January 09, 2023, 04:30:55 PM »
~~~~~~~~~
;
; sp4ce.asm
;
; alCoPaUL [GIMO][As][aBrA][NPA][b8]
; 10/6/2021
;
; nasm <dash>f win32 sp4ce.asm
; link sp4ce.obj /subsystem:console /defaultlib:msvcrt.lib /entry:m
;

you need msvcrt.lib..

bro, like wtf.. of course my code isn't compiling coz it's assembling..

go get the sdk for visual studio 2010 and get the appropriate .libs

Offline alCoPaUL

  • Jr. Member
  • *
  • Posts: 74
  • Country: ph
    • Webpage
Re: Help with Hello World and NASM on mingw64
« Reply #32 on: January 09, 2023, 04:36:49 PM »
and yo, did you even compare my posted source code, like the way it was written or how the control flow flows to your almost linear assembly structure?

like if you didn't delete my post in the EXAMPLE CODE section and actually tested it in a spare isolated computer, you should've had everything there to assemble properly and see what's up.

printf() is not that different with win32 apis. you can find printf() in the runtime dll, you can find win32 api from kernel32.dll

in linux, you just go syscalling forever to meet your needs (at least ms-dos goes INT (number here))


Offline alCoPaUL

  • Jr. Member
  • *
  • Posts: 74
  • Country: ph
    • Webpage
Re: Help with Hello World and NASM on mingw64
« Reply #33 on: January 09, 2023, 04:39:12 PM »
and again, you can use ld.exe with the appropriate C runtime lib in linux to link your nasm assembly object code that has printf().

you were insisting that those files are the same coz why? you used GCC in both - the C printf() hello world template and the assembly language code with printf().

and bro, you had the audacity to compare the file size of the assembly file that has printf() that you GCCed and the one that you LDed that has the SYSCALL meme.

go link the assembly code that has the printf() using LD.exe with it's appropriate library and let's talk after.
« Last Edit: January 09, 2023, 04:43:18 PM by alCoPaUL »