0% found this document useful (0 votes)
115 views

X86 Assembly/NASM Syntax

The document summarizes NASM syntax and provides examples of writing "Hello World" programs in NASM assembly for Linux and Windows. It discusses: - NASM uses Intel-like syntax and supports various object file formats - Single-line comments start with semicolon, macros are defined with %define - Examples of reading/writing with system calls on Linux and Windows - A "Hello World" program structure in NASM for Linux - Rewriting "Hello World" to use only Windows system calls - Rewriting to use C libraries and link with gcc

Uploaded by

Anilkumar Patil
Copyright
© © All Rights Reserved
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
115 views

X86 Assembly/NASM Syntax

The document summarizes NASM syntax and provides examples of writing "Hello World" programs in NASM assembly for Linux and Windows. It discusses: - NASM uses Intel-like syntax and supports various object file formats - Single-line comments start with semicolon, macros are defined with %define - Examples of reading/writing with system calls on Linux and Windows - A "Hello World" program structure in NASM for Linux - Rewriting "Hello World" to use only Windows system calls - Rewriting to use C libraries and link with gcc

Uploaded by

Anilkumar Patil
Copyright
© © All Rights Reserved
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
You are on page 1/ 6

X86 Assembly/NASM Syntax

< X86 Assembly


x86 Assembly
The Netwide Assembler is an x86 and x86-64 assembler that uses syntax similar to Intel. It supports a
variety o ob!e"t ile ormats# in"ludin$%
&. '()*+,64
+. (inux a.out
*. Net-./,)ree-./ a.out
4. 0.-/1. &6-bit,*+-bit ob!e"t iles
2. 3in*+,64 ob!e"t iles
6. 41))
5. 0a"h-1 *+,64
8. rd
NA.0 runs on both 6nix and 3indows,/1..
Contents
& NA.0 .yntax
&.& 4omments
&.+ 0a"ros
+ 'xample I,1 7(inux and -./8
* 9ello 3orld 7(inux8
4 9ello 3orld 76sin$ only 3in*+ system "alls8
2 9ello 3orld 76sin$ 4 libraries and (in:in$ with $""8
NASM Syntax
3i:ipedia has related inormation at Netwide Assembler
The Netwide Assembler 7NA.08 uses a syntax ;desi$ned to be simple and easy to understand# similar
to Intel<s but less "omplex;. This means that the operand order is dest then src# as opposed to the AT=T
style used by the >N6 Assembler. )or example#
mov ax, 9
loads the number ? into re$ister ax.
)or those usin$ $db with nasm# you "an set $db to use Intel-style disassembly by issuin$ the "ommand%
set disassembly-flavor intel
Comments
A sin$le semi-"olon is used or "omments# and un"tions the same as double slash in 4@@% the "ompiler
i$nores rom the semi"olon to the next newline.
Macros
NA.0 has powerul ma"ro un"tions# similar to 4<s prepro"essor. )or example#
%define newline 0xA
%define func(a, b) ((a) * (b) + 2)

func (, 22) ! ex"ands to (() * (22) + 2)

%defmacro "rint ! macro wit# one ar$ument
"us# dword % ! % means first ar$ument
call "rintf
add es", %
%endmacro

"rint mystrin$ ! will call "rintf
Example I/O (Linx and !S"#
To pass the :ernel a simple input "ommand on (inux# you would pass values to the ollowin$ re$isters
and then send the :ernel an interrupt si$nal. To read in a sin$le "hara"ter rom standard input 7su"h as
rom a user at their :eyboard8# do the ollowin$%
! read a byte from stdin
mov eax, & ! & is reco$ni'ed by t#e system as meanin$ (read(
mov ebx, 0 ! read from standard in"ut
mov ecx, variable ! address to "ass to
mov edx, ! in"ut len$t# (one byte)
int 0x)0 ! call t#e *ernel
Ater the int 0x)0# eax will "ontain the number o bytes read. I this number is < A# there was a
read error o some sort.
1utputtin$ ollows a similar "onvention%
! "rint a byte to stdout
mov eax, % ! t#e system inter"rets % as (write(
mov ebx, ! standard out"ut ("rint to terminal)
mov ecx, variable ! "ointer to t#e value bein$ "assed
mov edx, ! len$t# of out"ut (in bytes)
int 0x)0 ! call t#e *ernel
-./ systems 70a"1. X in"luded8 use similar system "alls# but "onvention to exe"ute them is
dierent. 3hile on (inux you pass system "all ar$uments in dierent re$isters# on -./ systems they
are pushed onto sta": 7ex"ept the system "all number# whi"h is put into eax# the same way as in (inux8.
-./ version o the "ode above%
! read a byte from stdin
mov eax, & ! sys+read system call
"us# dword ! in"ut len$t#
"us# dword variable ! address to "ass to
"us# dword 0 ! read from standard in"ut
"us# eax
int 0x)0 ! call t#e *ernel
add es", , ! move bac* t#e stac* "ointer

! write a byte to stdout
mov eax, % ! sys+write system call
"us# dword ! out"ut len$t#
"us# dword variable ! memory address
"us# dword ! write to standard out"ut
"us# eax
int 0x)0 ! call t#e *ernel
add es", , ! move bac* t#e stac* "ointer

! -uit t#e "ro$ram
mov eax, ! sys+exit system call
"us# dword 0 ! "ro$ram return value
"us# eax
int 0x)0 ! call t#e *ernel
$ello %orld (Linx#
-elow we have a simple 9ello world example# it lays out the basi" stru"ture o a nasm pro$ram%
$lobal +start

section .data
! Ali$n to t#e nearest 2 byte boundary, must be a "ower of two
ali$n 2
! /trin$, w#ic# is 0ust a collection of bytes, 0xA is newline
str1 db 23ello, world42,0xA
str5en1 e-u 6-str

section .bss

section .text
+start1

!
! o" dst, src
!
!
! 7all write(2) syscall1
! ssi'e+t write(int fd, const void *buf,
si'e+t count)
!
mov edx, str5en ! Ar$ t#ree1 t#e len$t# of t#e strin$
mov ecx, str ! Ar$ two1 t#e address of t#e strin$
mov ebx, ! Ar$ one1 file descri"tor, in t#is case stdout
mov eax, % ! /yscall number, in t#is case t#e write(2)
syscall1
int 0x)0 ! 8nterru"t 0x)0

!
! 7all exit(&) syscall
! void exit(int status)
!
mov ebx, 0 ! Ar$ one1 t#e status
mov eax, ! /yscall number1
int 0x)0
In order to assemble# lin: and run the pro$ram we need to do the ollowin$%
6 nasm -f elf&2 -$ #ello9orld.asm
6 ld -$ #ello9orld.o
6 .:a.out
$ello %orld (&sin' only %in() system calls#
In this example we are $oin$ to rewrite the hello world example usin$ 3in*+ system "alls. There are
several ma!or dieren"es%
&. The intermediate ile will be a 0i"rosot 3in*+ 7i*868 ob!e"t ile
+. 3e will avoid usin$ interrupts sin"e they may not be portable and thereore we need to brin$ in
several "alls rom :ernel*+ /((
$lobal +start

extern +;et/td3andle<%
extern +9rite7onsoleA<20
extern +=xit>rocess<%

section .data
str1 db 2#ello, world2,0xA
str5en1 e-u 6-str

section .bss
num7#ars9ritten1 resb

section .text
+start1

!
! 3A?@5= 98?A>8 ;et/td3andle( +8n+ @9AB@ n/td3andle ) !
!
"us# dword - ! Ar$1 re-uest #andle for standard out"ut
call +;et/td3andle<% ! Besult1 in eax

!
! CAA5 98?A>8 9rite7onsole(
! +8n+ 3A?@5= #7onsoleAut"ut,
! +8n+ const DA8@ *l"Cuffer,
! +8n+ @9AB@ n?umberAf7#arsEo9rite,
! +Aut+ 5>@9AB@ l"?umberAf7#ars9ritten,
! +Beserved+ 5>DA8@ l"Beserved ) !
!
"us# dword 0 ! Ar$F1 Gnused so 0ust use 'ero
"us# num7#ars9ritten ! Ar$%1 "us# "ointer to num7#ars9ritten
"us# dword str5en ! Ar$&1 "us# len$t# of out"ut strin$
"us# str ! Ar$21 "us# "ointer to out"ut strin$
"us# eax ! Ar$1 "us# #andle returned from +;et/td3andle
call +9rite7onsoleA<20


!
! DA8@ 98?A>8 =xit>rocess( +8n+ G8?E u=xit7ode ) !
!
"us# dword 0 ! Ar$1 "us# exit code
call +=xit>rocess<%
In order to assemble# lin: and run the pro$ram we need to do the ollowin$. This example was run
under "y$win# in a 3indows "ommand prompt the lin: step would be dierent. In this example we use
the -e "ommand line option when invo:in$ ld to spe"iy the entry point or pro$ram exe"ution.
1therwise we would have to use +9inHain<, as the entry point rather than +start. 1ne last note#
9rite7onsole() does not behave well within a "y$win "onsole# so in order to see output the inal
exe should be run within a 3indows "ommand prompt%
6 nasm -f win&2 -$ #ello9orld9in&2.asm
6 ld -e +start #ello9orldwin&2.ob0 -l*ernel&2 -o #ello9orld9in&2.exe
$ello %orld (&sin' C libraries and Lin*in' +it, 'cc#
In this example we will rewrite 9ello 3orld to use "rintf(&) rom the 4 library and lin: usin$
$cc. This has the advanta$e that $oin$ rom (inux to 3indows reBuires minimal sour"e "ode "han$es
and a sli$htly dierent assemble and lin: steps. In the 3indows world this has the additional beneit
that the lin:in$ step will be the same in the 3indows "ommand prompt and "y$win. There are several
ma!or "han$es%
&. The (#ello, world( strin$ now be"omes the ormat strin$ or "rintf(&) and thereore
needs to be null terminated. This also means we do not need to expli"itly spe"iy it<s len$th
anymore.
+. $"" expe"ts the entry point or exe"ution to be main
*. 0i"rosot will preix un"tions usin$ the cdecl "allin$ "onvention with a unders"ore. .o
main and "rintf will be"ome +main and +"rintf respe"tively in the 3indows
development environment.
$lobal main

extern "rintf

section .data
fmt/tr1 db 2#ello, world2,0xA,0

section .text
main1

sub es", % ! Allocate s"ace on t#e stac* for one % byte
"arameter

lea eax, Ifmt/trJ
mov Ies"J, eax ! Ar$1 "ointer to format strin$
call "rintf ! 7all "rintf(&)1
! int "rintf(const c#ar *format, ...)!

add es", % ! >o" stac* once

ret
In order to assemble# lin: and run the pro$ram we need to do the ollowin$.
6 nasm -felf&2 #ello9orld$cc.asm
6 $cc #ello9orld$cc.o -o #ello9orld$cc
The 3indows version with preixed unders"ores%
$lobal +main

extern +"rintf ! Gncomment under 9indows

section .data
fmt/tr1 db 2#ello, world2,0xA,0

section .text
+main1

sub es", % ! Allocate s"ace on t#e stac* for one % byte
"arameter

lea eax, Ifmt/trJ
mov Ies"J, eax ! Ar$1 "ointer to format strin$
call +"rintf ! 7all "rintf(&)1
! int "rintf(const c#ar *format, ...)!

add es", % ! >o" stac* once

ret
In order to assemble# lin: and run the pro$ram we need to do the ollowin$.
6 nasm -fwin&2 #ello9orld$cc.asm
6 $cc #ello9orld$cc.o -o #ello9orld$cc

You might also like