; Example file for nasm.xml kate syntax file ; compile with `nasm example.asm -f elf -o example.o` ; and link with 'gcc example.o -o example` ; Public domain ; kate:hl Intel x86 (NASM); section hellodd'Hello World',0x0A,0h printf_paramdd'%s',0q section extern printf global main
pushebp movebp,esp push hello push printf_param call printf moveax,0b leave ret NULLEQU0; Constants STD_OUTPUT_HANDLEEQU-11 extern GetStdHandle ; Import external symbols global Start ; Export symbols. The entry point section; Initialized data segment Messagedb"Console Message 64",0Dh,0Ah MessageLengthEQU$-Message ; Address of this line ($) - address of Message section; Uninitialized data segment alignb8 Writtenresq1 section; Code segment
subRSP,8; Align the stack to a multiple of 16 bytes movECX, STD_OUTPUT_HANDLE call GetStdHandle movqword[REL StandardHandle],RAX subRSP,32+8+8; Shadow space + 5th parameter + align stack ; to a multiple of 16 bytes movRCX,qword[REL StandardHandle]; 1st parameter leaRDX,[REL Message]; 2nd parameter movR8, MessageLength ; 3rd parameter movqword[RSP+4*8], NULL ; 5th parameter ; Message Box, 64 bit. V1.02
xorECX,ECX; 1st parameter leaRDX,[REL MessageBoxText]; 2nd parameter leaR8,[REL MessageBoxCaption]; 3rd parameter movR9D, MB_YESNO | MB_DEFBUTTON2 ; 4th parameter. 2 constants ORed together call MessageBoxA cmpRAX, IDNO ; Check the return value for "No" je extern _GetStdHandle@4 ; Import external symbols
call _WriteFile@20 section; Initialized data segment Static1Colourdd0F0F0F0h, Edit2resq1 %defineScreen.WidthRBP-160; 4 bytes %defineClientAreaRBP-152; RECT structure. 16 bytes movdword[wc.cbSize],80; [RBP - 136] movdword[wc.style], CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW ; [RBP - 132] movqword[wc.lpfnWndProc],RAX; [RBP - 128] movqword[wc.hIcon],RAX; [RBP - 104] movdword[RSP+4*8],EAX; X position, now centred cmpqword[uMsg], WM_CLOSE ; [RBP + 24] je WMCLOSE call DestroyWindow ; Send a WM_DESTROY message jmp Return.WM_Processed movEDX,0604060h call SetBkColor movEDX,0005000h
db0x55; just the byte 0x55
db0x55,0x56,0x57; three bytes in succession
db'a',0x55; character constants are OK
db'hello',13,10,'$'; so are string constants
dw0x1234; 0x34 0x12
dw'a'; 0x61 0x00 (it's just a number)
dw'ab'; 0x61 0x62 (character constant)
dw'abc'; 0x61 0x62 0x63 0x00 (string)
dd0x12345678; 0x78 0x56 0x34 0x12
dd1.234567e20; floating-point constant
dq0x123456789abcdef0; eight byte constant
dq1.234567e20; double-precision float
dt1.234567e20; extended-precision float
db33
db(44); Integer expression ; db (44,55) ; Invalid - error
db%(44,55)
db%('XX','YY')
db('AA'); Integer expression - outputs single byte
db%('BB'); List, containing a string
db?
db6 dup (33)
db6 dup (33,34)
db6 dup (33,34),35
db7 dup (99)
db7 dup dword(?,word?,?)
dwbyte(?,44)
dw3 dup (0xcc,4 dup byte('PQR'),?),0xabcd
dd16 dup (0xaaaa,?,0xbbbbbb)
dd64 dup (?)
db`\u263a`; UTF-8 smiley face
db`\xe2\x98\xba`; UTF-8 smiley face
db0E2h,098h,0BAh; UTF-8 smiley face resb64; reserve 64 bytes resw1; reserve a word db64 dup (?); reserve 64 bytes dw?; reserve a word
incbin"file.dat"; include the whole file
incbin"file.dat",1024; skip the first 1024 bytes
incbin"file.dat",1024,512; skip the first 1024, and ; actually include at most 512 messagedb'hello, world' msglenequ$-message db'hello, world' times64-$+buffer db' ' bndstx[rbx*1+rax+0x3], bnd0 ; GAS - '*1' indecates an index reg VDIVPSzmm4,zmm5,dword[rbx]{1to16}; single-precision float VDIVPSzmm4,zmm5,zword[rbx]; packed 512 bit memory movax,200; decimal movax,0200; still decimal movax,0200d; explicitly decimal movax,0d200; also decimal movax,0c8h; hex movax,$0c8; hex again: the 0 is required movax,0xc8; hex yet again movax,0hc8; still hex movax,310q; octal movax,310o; octal again movax,0o310; octal yet again movax,0q310; octal yet again movax,11001000b; binary movax,1100_1000b; same binary constant movax,1100_1000y; same binary constant once more movax,0b1100_1000; same binary constant yet again movax,0y1100_1000; same binary constant yet again %defineu(x)__?utf16?__(x) %definew(x)__?utf32?__(x)
dw u('C:\WINDOWS'),0; Pathname in UTF-16
dd w(`A + B = \u206a`),0; String in UTF-32
db-0.2; "Quarter precision"
dw-0.5; IEEE 754r/SSE5 half precision
dd1.2; an easy one
dd1.222_222_222; underscores are permitted
dd0x1p+2; 1.0x2^2 = 4.0
dq0x1p+32; 1.0x2^32 = 4 294 967 296.0
dq1.e10; 10 000 000 000.0
dq1.e+10; synonymous with 1.e10
dq1.e-10; 0.000 000 000 1
dt3.141592653589793238462; pi
do1.e+4000; IEEE 754r quad precision movrax,__?float64?__(3.141592653589793238462) movrax,0x400921fb54442d18 %defineInf__?Infinity?__ %defineNaN__?QNaN?__
dq+1.5,-Inf, NaN ; Double-precision constants
dt12_345_678_901_245_678p
dt-12_345_678_901_245_678p
dt+0p33
dt33p
dq b *(a // b)+(a b) call(seg procedure):procedure call weird_seg:(procedure wrt weird_seg) pushdword33 pushstrictdword33
times(label-$)db0 db'Where am I?' times(label-$+1)db0 db'NOW where am I?' label1; some code .loop ; some more code jne ret ; a non-local label ; this is really label1.local ; this is a special symbol ; another non-local label ; this is really label2.local jmp; this will jump three lines up %defineTHIS_VERY_LONG_MACRO_NAME_IS_DEFINED_TO \ THIS_VALUE %definectrl0x1F& %defineparam(a,b)((a)+(a)*(b)) movbyte[param(2,ebx)], ctrl 'D' movbyte[(2)+(2)*(ebx)],0x1F&'D' %definea(x)1+b(x) %defineb(x)2*x movax,a(8) %definefoo(a,b); no arguments, (a,b) is the expansion %definebar(a,b); two arguments, empty expansion %defineereg(foo,) e %+ foo moveax,ereg(dx,cx) %definexyzzy(=expr,&val) expr, str %defineplugh(x) xyzzy(x,x) db plugh(3+5),`\0`; Expands to: db 8, "3+5", `\0` movax,Foo%[__?BITS?__]; The Foo value %xdefineBar Quux ; Expands due to %xdefine %defineBar%[Quux]; Expands due to %[...] %defineBDASTART400h; Start of BIOS data area struc tBIOSDA ; its structure .COM1addrRESW1 .COM2addrRESW1 ; ..and so on endstruc movax,BDASTART + tBIOSDA.COM1addr movbx,BDASTART + tBIOSDA.COM2addr ; Macro to access BIOS variables by their names (from tBDA): %idefineFoo mov %?,%?? %idefinekeyword$%? %idefinepause$%?; Hide the PAUSE instruction %definefoo bar %undeffoo moveax, foo %assigni i+1 %defstrtest TEST %definetest'TEST' %defstrPATH%!PATH ; The operating system PATH variable %deftoktest'TEST' %definetest TEST %definegreedy(a,b,c+) a +66%, b *3%, c db greedy(1,2); db 1 + 66, 2 * 3 db greedy(1,2,3); db 1 + 66, 2 * 3, 3 db greedy(1,2,3,4); db 1 + 66, 2 * 3, 3, 4 db greedy(1,2,3,4,5); db 1 + 66, 2 * 3, 3, 4, 5 %macrosilly2 %2: db%1 %endmacro silly'a', letter_a ; letter_a: db 'a' silly'ab', string_ab ; string_ab: db 'ab' silly{13,10}, crlf ; crlf: db 13,10 %pragmapreproc sane_empty_expansion %macrompar1-* db%{3:5} db%{-1:-3} %endmacro mpar1,2,3,4,5,6 %macrodie0-1"Painful program death has occurred." writefile2,%1 movax,0x4c01 int0x21 %endmacro %macromultipush1-* %rep %0 push%1 %rotate 1 %endrep j%-1 ret %endmacro %macrofoo1.nolist %endmacro %macropushparam1 %ifidni %1,ip call %else push%1 %endif %endmacro %assigni0 %rep 64 incword[table+2*i] %assigni i+1 %endrep %assigni0 %assignj1 %rep 100 %ifj>65535 %exitrep %endif dw j %assignk j+i %assigni j %assignj k %endrep fib_numberequ($-fibonacci)/2 %include "macros.mac" %ifndefMACROS_MAC %defineMACROS_MAC ; now define some macros %endif %pathsearchMyFoo"foo.bin" %imacroincbin1-2+0 %pathsearchdep%1 %dependdep incbin dep,%2 %endmacro %usealtreg %use 'altreg' %pushfoobar %macrorepeat0 %pushrepeat %$begin: %endmacro %macrountil1 j%-1%$begin %pop %endmacro %define %$localmac3 %macroelse0 %ifctxif %replelse jmp%$ifend %$ifnot: %else %error "expected`if' before `else'" %endif %endmacro %macroendif0 %ifctxif %$ifnot: %pop %elifctxelse %$ifend: %pop %else %error "expected`if' or `else' before `endif'" %endif %endmacro %pushmycontext; save the current context %stacksizesmall; tell NASM to use bp %assign %$localsize0; see text for explanation %localold_ax:word, old_dx:word enter%$localsize,0; see text for explanation mov[old_ax],ax; swap ax & bx movcx,[old_dx] leave; restore old bp ret; %pop; restore original context %ifdefF1 ; do some setup %elifdefF2 ; do some different setup %else %error "Neither F1 nor F2 was defined." %endif %ifdefF1 ; do some setup %elifdefF2 ; do some different setup %else %warning "Neither F1 nor F2 was defined, assuming F1." %defineF1 %endif%if foo >64 %assignfoo_over foo-64 %errorfoo is foo_over bytes too large %endif db__?NASM_VER?__ struc mytype resd1 resb32 endstruc %usealtreg %macrowritefile2+ [section] db%2 __?SECT?__ movdx, movcx,- movbx,%1 movah,0x40 int0x21 %endmacro DEFAULTBND call foo ; BND will be prefixed nobnd call foo ; BND will NOT be prefixed global _main global hashlookup:function, hashtable:data common intvar 4 static foo ; codes %pragmamacho lprefix L_ ; The most common conventions %pragmaoutput gprefix _ %pragmaoutput lprefix L_ ; ELF uses a different convention %pragmaelf gprefix ; empty %pragmaelf lprefix section rdata align=4 dd main wrt dd main_end wrt dd xmain wrt section rdata align=8 db9,0,0,0 dd handler wrt section info db'/defaultlib:user32.lib /defaultlib:msvcrt.lib '