NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: Jaafar on August 06, 2022, 09:52:02 AM
-
Hi dear asm community,
Info: I am running Windows10 x64bit .
I am a newbie and want to start learning to code in assembly.
I have installed nasm.exe and and have written my first console "hello world" code in asm (code snippet copied from the internet) BUT I can't for the life of me link or compile the file. The cmd prompt keeps saying can't recognize the commands.
I have spent 2 entire days trynig to link and compile the asm code but without any luck. This is so frustrating as I just want to dive into writing asm code.
Can anyone please guide me step by step ?
Regards.
-
Hi Jaafar,
Welcome to the forum.
Good start telling us what OS you're running! Next, you will probably have to tell us which linker you're using (or trying to use). "Golink" is pretty popular, "ld" is available, Microsoft's "link" will work - you want the "incremental" version, not the "segmented" version... Maybe others(?).
Maybe I shouldn't mention this, but others in your position have gotten ahold of a Linux snippet and are trying to use that on Windows - won't work...
So... good start, but keep telling us what you tried and what happened. Nasm will do a lot of different things, and linkers too...
I haven't run Windows for a long time, but surely someone will be able to help you.
Best,
Frank
-
Hi Frank. Thanks for replying.
I donwloaded and installed GoLink.exe but I don't know how to use it. I am a complete beginner.
Do I need to place the Golink.exe in the same folder as the nasm.exe ? do I need to add any folders to the windows environnement variable Path ? and what about compiling ?
I wish I could find a step by step guide for dummies.
Thanks again.
-
Hi again Jaafar,
We may need to create that step by step guide.
We were all complete beginners at one time. That can be fixed.
I am old and tired, My memory is all shot... among other things. That may not be so easy to fix.
I KNOW I have seen simple examples right on this forum... but can't find 'em right now.
Where did you find the code? Any help there?
You shouldn't need to put Golink in the same folder as Nasm. You will want to put them both on your path. That's one step.
Assemble with "nasm -f win64 myfile.asm". Other options are possible but probably not necessary. That's one step.
Now... "golink /console myfile.o ... some more stuff" :) That should do it. The "more stuff" might be like :"user64.dll"? Maybe :"kernel64.dll"? Sorry I can't be more help there.
It gets easier after the first time. But you know that, that's what you're asking... If you don't get any help with Golink, fool with it 'til it works, :) Show us more of what you did, if you need to.
Best,
Frank
-
Please post the code you are struggling with, as that may help us determine what the problem is. For example, 16-bit code won't run in a 64-bit Windows console.
-
Thanks.
I have taken the code snippet from here :
https://www.davidgrantham.com/nasm-console64/
; Console Message, 64 bit. V1.03
NULL EQU 0 ; Constants
STD_OUTPUT_HANDLE EQU -11
extern GetStdHandle ; Import external symbols
extern WriteFile ; Windows API functions, not decorated
extern ExitProcess
global Start ; Export symbols. The entry point
section .data ; Initialized data segment
Message db "Console Message 64", 0Dh, 0Ah
MessageLength EQU $-Message ; Address of this line ($) - address of Message
section .bss ; Uninitialized data segment
alignb 8
StandardHandle resq 1
Written resq 1
section .text ; Code segment
Start:
sub RSP, 8 ; Align the stack to a multiple of 16 bytes
sub RSP, 32 ; 32 bytes of shadow space
mov ECX, STD_OUTPUT_HANDLE
call GetStdHandle
mov qword [REL StandardHandle], RAX
add RSP, 32 ; Remove the 32 bytes
sub RSP, 32 + 8 + 8 ; Shadow space + 5th parameter + align stack
; to a multiple of 16 bytes
mov RCX, qword [REL StandardHandle] ; 1st parameter
lea RDX, [REL Message] ; 2nd parameter
mov R8, MessageLength ; 3rd parameter
lea R9, [REL Written] ; 4th parameter
mov qword [RSP + 4 * 8], NULL ; 5th parameter
call WriteFile ; Output can be redirect to a file using >
add RSP, 48 ; Remove the 48 bytes
xor ECX, ECX
call ExitProcess
-
Super! That is exactly the code I had in mind. It's been a long time since I've run Windows, but that's the way I remember it. Hooray for David Grantham! I don't think he's a member of this forum, but we would love to have him!
He goes on to give linking instructions:
Link
golink /entry:Start /console kernel32.dll user32.dll ConsoleMessage64.obj
I was pretty close... (counts in horseshoes and nuclear weapons) This is "or" Polink. you don't need both (I'm quite sure).
polink /ENTRY:Start /SUBSYSTEM:CONSOLE /LIBPATH:c:\lib64 kernel32.lib user32.lib ConsoleMessage64.obj
That should do it. Do you need "permission" for the directory/folder in Windows these days?
We're on our way to that step by step guide. Maybe should start with "Hpw do I open a console?" Used to be "command.com" (hasn't really been a ".com" file for a long time). Now it's "cmd.exe", right?
Thanks, Jaadae!
Best,
Frank
-
Simplier and with ANSI:
; test.asm
;
; nasm -fwin64 -o test.o test.asm
; ld -s -o test.exe test.o -lkernel32
;
bits 64
default rel
%define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4
section .bss
mode:
resd 1
section .rodata
msg:
db `\033[1;31mH\033[1;32me\033[1;33ml\033[1;34ml\033[1;35mo\033[m\r\n`
msg_len equ $ - msg
section .text
; From kernel32.dll
extern __imp_GetStdHandle
extern __imp_GetConsoleMode
extern __imp_SetConsoleMode
extern __imp_WriteConsoleA
extern __imp_ExitProcess
global _start
_start:
mov ecx,-11 ; STD_OUTPUT_HANDLE
call [__imp_GetStdHandle]
mov rbx,rax ; Preserve handle in RBX.
; Enable VT100 on Windows Terminal.
mov rcx,rax
lea rdx,[mode]
call [__imp_GetConsoleMode]
mov edx,[mode]
or edx,ENABLE_VIRTUAL_TERMINAL_PROCESSING
mov rcx,rbx
call [__imp_SetConsoleMode]
; Write to Console.
mov rcx,rbx
lea rdx,[msg]
mov r8d,msg_len
xor r9d,r9d
push 0
call [__imp_WriteConsoleA]
xor ecx,ecx
jmp [__imp_ExitProcess]
-
msg:
db `\033[1;31mH\033[1;32me\033[1;33ml\033[1;34ml\033[1;35mo\033[m\r\n`
Say what?
Best,
Frank
-
msg:
db `\033[1;31mH\033[1;32me\033[1;33ml\033[1;34ml\033[1;35mo\033[m\r\n`
Say what?
Hello
-
Cool!
Thank you!
Best,
Frank
-
Just to point out that ANSI processing is enabled by default on UNIXes in general. The same code, for Linux, is simplier:
; nasm -felf64 -o test.o test.asm
; ld -s -o test test.o
bits 64
default rel
section .rodata
; To learn abour ANSI codes:
; https://en.wikipedia.org/wiki/ANSI_escape_code
;
; More precisely, we should see VT-100/VT-101 control codes:
; https://vt100.net/docs/vt510-rm/chapter4.html
msg:
db `\033[1;31mH\033[1;32me\033[1;33ml\033[1;34ml\033[1;35mo\033[m\n`
msg_length equ $ - msg
section .text
global _start
_start:
mov eax,1 ; write syscall
mov edi,eax ; stdout
lea rsi,[msg]
mov edx,msg_length
syscall
mov eax,60 ; exit syscall
xor edi,edi
syscall
But this is UNIX code... On Windows we must enable terminal emulation to use ANSI codes AND use Console API.
PS: Use WriteConsoleA, not WriteFile.
WriteFile won't work in every Windows versions because, the terminal HANDLE isn't a file descriptor, as in UNIXes... If you want to read/write from/to terminal you should use Win32 Console API.
[]s
Fred
-
I never realized that ANSI was enabled on Linux, or I would have tried your message instead of asking such a foolish question! I will try it soon. I remember ANSI vaguely from the good old DOS days. Once again, thank you!
Best,
Frank
-
Cool! Just like your picture. I had no idea I could do that in Linux. We live and learn.
To get back to Jaafar's question... How are you doing? Got anything to link yet? Either version? Preferably both?
Best,
Frank
-
Hi All,
I think he may have fixed his problem with adding things to his windows environment. Sounds like the errors you would get for not doing so. Mind you that example is going to fly if you just click on the .exe created, you would be lucky to even see the cmd window displayed.
And I just tried it, it assembles and compiles just fine.
John
-
Thanks John,
So maybe we need to tell beginners to always wait for a keystroke before exiting?
I dunno.
Best,
Frank
-
Thanks John,
So maybe we need to tell beginners to always wait for a keystroke before exiting?
I dunno.
Best,
Frank
-
Thanks John,
So maybe we need to tell beginners to always wait for a keystroke before exiting?
I dunno.
Best,
Frank
-
Ahhh... once would have been enough. Sorry.
Dunno if we're going to hear from Jaafar again or not. Whatever...
Best,
Frank