NASM
| Òèï | |
|---|---|
| Îïåðàöèîííàÿ ñèñòåìà | |
| Ïîñëåäíÿÿ âåðñèÿ | |
| Ëèöåíçèÿ |
LGPL, ñ âåðñèè 2.07 â óïðîù¸ííàÿ ëèöåíçèÿ BSD |
| Ñàéò |
NASM (Netwide Assembler) â ñâîáîäíûé (LGPL è ëèöåíçèÿ BSD) àññåìáëåð äëÿ àðõèòåêòóðû Intel x86. Èñïîëüçóåòñÿ äëÿ íàïèñàíèÿ 16-, 32- è 64-áèòíûõ ïðîãðàìì.
Ñîäåðæàíèå |
[ïðàâèòü] Èñòîðèÿ
NASM áûë ñîçäàí Ñàéìîíîì Òýòõåìîì ñîâìåñòíî ñ Þëèàíîì Õîëëîì è â íàñòîÿùåå âðåìÿ ðàçâèâàåòñÿ íåáîëüøîé êîìàíäîé ðàçðàáîò÷èêîâ íà SourceForge.net. Ïåðâîíà÷àëüíî îí áûë âûïóùåí ñîãëàñíî åãî ñîáñòâåííîé ëèöåíçèè, íî ïîçæå ýòà ëèöåíçèÿ áûëà çàìåíåíà íà GNU LGPL ïîñëå ìíîæåñòâà ïðîáëåì, âûçâàííûõ âûáîðîì ëèöåíçèè. Íà÷èíàÿ ñ âåðñèè 2.07 ëèöåíçèÿ çàìåíåíà íà «óïðîù¸ííóþ BSD» (BSD èç 2 ïóíêòîâ).
NASM ìîæåò ðàáîòàòü íà ïëàòôîðìàõ, îòëè÷íûõ îò x86, òàêèõ êàê SPARC è PowerPC, îäíàêî êîä îí ãåíåðèðóåò òîëüêî äëÿ x86 è x86-64[1].
NASM óñïåøíî êîíêóðèðóåò ñî ñòàíäàðòíûì â Linux- è ìíîãèõ äðóãèõ UNIX-ñèñòåìàõ àññåìáëåðîì gas.[2][3][4] Ñ÷èòàåòñÿ, ÷òî êà÷åñòâî äîêóìåíòàöèè ó NASM âûøå, ÷åì ó gas.[4] Êðîìå òîãî, àññåìáëåð gas ïî óìîë÷àíèþ[5] èñïîëüçóåò AT&T-ñèíòàêñèñ, îðèåíòèðîâàííûé íà ïðîöåññîðû íå îò Intel, â òî âðåìÿ êàê NASM èñïîëüçóåò âàðèàíò òðàäèöèîííîãî äëÿ x86-àññåìáëåðîâ Intel-ñèíòàêñèñà; Intel-ñèíòàêñèñ èñïîëüçóåòñÿ âñåìè àññåìáëåðàìè äëÿ ïîä DOS/Windows, íàïðèìåð, MASM, TASM, fasm.
[ïðàâèòü] Ñèíòàêñèñ ÿçûêà
 NASM èñïîëüçóåòñÿ Intel-ñèíòàêñèñ çàïèñè èíñòðóêöèé. Ïðåäëîæåíèå ÿçûêà àññåìáëåðà NASM (ñòðîêà ïðîãðàììû) ìîæåò ñîñòîÿòü èç ñëåäóþùèõ ýëåìåíòîâ:
Ìåòêà Èíñòðóêöèÿ Îïåðàíäû Êîììåíòàðèé
Îïåðàíäû îòäåëÿþòñÿ ìåæäó ñîáîé çàïÿòîé. Ïåðåä ñòðîêîé è ïîñëå èíñòðóêöèè ìîæíî èñïîëüçîâàòü ëþáîå êîëè÷åñòâî ïðîáåëüíûõ ñèìâîëîâ. Êîììåíòàðèé íà÷èíàåòñÿ ñ òî÷êè ñ çàïÿòîé, à êîíöîì êîììåíòàðèÿ ñ÷èòàåòñÿ êîíåö ñòðîêè.  êà÷åñòâå èíñòðóêöèè ìîæåò èñïîëüçîâàòüñÿ êîìàíäà èëè ïñåâäîêîìàíäà (äèðåêòèâà êîìïèëÿòîðà). Åñëè ñòðîêà î÷åíü äëèííàÿ, òî å¸ ìîæíî ïåðåíåñòè íà ñëåäóþùóþ, èñïîëüçóÿ îáðàòíûé ñëåø \, ïîäîáíî òîìó, êàê ýòî äåëàåòñÿ â ÿçûêå Ñè.
[ïðàâèòü] Êîìïèëÿöèÿ è êîìïîíîâêà
NASM êîìïèëèðóåò ïðîãðàììû ïîä ðàçëè÷íûå îïåðàöèîííûå ñèñòåìû â ïðåäåëàõ x86-ñîâìåñòèìûõ ïðîöåññîðîâ. Íàõîäÿñü â îäíîé îïåðàöèîííîé ñèñòåìå, ìîæíî áåñïðåïÿòñòâåííî îòêîìïèëèðîâàòü èñïîëíÿåìûé ôàéë äëÿ äðóãîé.
Êîìïèëÿöèÿ ïðîãðàìì â NASM ñîñòîèò èç äâóõ ýòàïîâ. Ïåðâûé â àññåìáëèðîâàíèå, âòîðîé â êîìïîíîâêà. Íà ýòàïå àññåìáëèðîâàíèÿ ñîçäà¸òñÿ îáúåêòíûé êîä.  í¸ì ñîäåðæèòñÿ ìàøèííûé êîä ïðîãðàììû è äàííûå, â ñîîòâåòñòâèè ñ èñõîäíûì êîäîì, íî èäåíòèôèêàòîðû (ïåðåìåííûå, ñèìâîëû) ïîêà íå ïðèâÿçàíû ê àäðåñàì ïàìÿòè. Íà ýòàïå êîìïîíîâêè èç îäíîãî èëè íåñêîëüêèõ îáúåêòíûõ ìîäóëåé ñîçäà¸òñÿ èñïîëíÿåìûé ôàéë (ïðîãðàììà). Îïåðàöèÿ êîìïîíîâêè ñâÿçûâàåò èäåíòèôèêàòîðû, îïðåäåë¸ííûå â îñíîâíîé ïðîãðàììå, ñ èäåíòèôèêàòîðàìè, îïðåäåë¸ííûìè â îñòàëüíûõ ìîäóëÿõ, ïîñëå ÷åãî âñåì èäåíòèôèêàòîðàì äàþòñÿ îêîí÷àòåëüíûå àäðåñà ïàìÿòè èëè îáåñïå÷èâàåòñÿ èõ äèíàìè÷åñêîå âûäåëåíèå.
Äëÿ êîìïîíîâêè îáúåêòíûõ ôàéëîâ â èñïîëíÿåìûå â Windows ìîæíî èñïîëüçîâàòü ñâîáîäíûé áåñïëàòíî ðàñïðîñòðàíÿåìûé êîìïîíîâùèê alink[3](äëÿ 64-õ áèòíûõ ïðîãðàìì êîìïîíîâùèê GoLink), à â Linux â êîìïîíîâùèê ld, êîòîðûé åñòü â ëþáîé âåðñèè ýòîé îïåðàöèîííîé ñèñòåìû.
Äëÿ àññåìáëèðîâàíèÿ ôàéëà íóæíî ââåñòè ñëåäóþùóþ êîìàíäó:
nasm -f format filename -o output
[ïðàâèòü] Èíñòðóêöèè ïåðåõîäà
Êîìïèëÿòîð îáðàáàòûâàåò òåêñò ïðîãðàììû â íåñêîëüêî ïðîõîäîâ, áëàãîäàðÿ ÷åìó ìîæíî èíñòðóêöèè ïåðåõîäà ðàçìåùàòü äî îáúÿâëåíèÿ ñîîòâåòñòâóþùèõ ìåòîê.
 êîìàíäàõ óñëîâíîãî è áåçóñëîâíîãî (jmp) ïåðåõîäîâ èñïîëüçóåòñÿ ïî óìîë÷àíèþ áëèæíèé òèï ïåðåõîäîâ â near. Ïîýòîìó ïðè âîçìîæíîñòè êîðîòêîãî ïåðåõîäà, ÷òîáû íå çàâûñèòü ðàçìåð ïðîãðàììû íà ëèøíèé áàéò, íåîáõîäèìî ñïåöèàëüíî óêàçàòü òèï ïåðåõîäà short. Ñ âåðñèè 0.98.09b áûëè äîáàâëåíû îïöèè îïòèìèçàöèè -Ox, êîòîðûå ïîçâîëÿþò àâòîìàòè÷åñêè îïòèìèçèðîâàòü ðàçìåð èíñòðóêöèé ïåðåõîäà[6], â áîëåå ðàííèõ âåðñèÿõ èëè áåç òàêèõ îïöèé ìèíèìàëüíûé ðàçìåð ïðîãðàììû ìîæíî ïîëó÷èòü òîëüêî ðó÷íîé ìîäèôèêàöèåé èñõîäíîãî êîäà.
[ïðàâèòü] Ôîðìàò âûõîäíûõ ôàéëîâ
NASM ïîääåðæèâàåò ìíîæåñòâî ôîðìàòîâ âûõîäíûõ ôàéëîâ, ñðåäè íèõ[7]:
- bin â ôàéë ïðîèçâîëüíîãî ôîðìàòà, îïðåäåëÿåìîãî òîëüêî èñõîäíûì êîäîì. Ïðèãîäåí êàê äëÿ ôàéëîâ äàííûõ, òàê è äëÿ ìîäóëåé ñ èñïîëíÿåìûìè êîäàìè â íàïðèìåð, ñèñòåìíûõ çàãðóç÷èêîâ, îáðàçîâ ÏÇÓ, ìîäóëåé îïåðàöèîííûõ ñèñòåì, äðàéâåðîâ .SYS â MS-DOS èëè èñïîëíÿåìûõ ôàéëîâ .COM.
- obj â îáúåêòíûé ìîäóëü â ôîðìàòå OMF, ñîâìåñòèìûé ñ MASM è TASM.
- win32 è win64 â îáúåêòíûé ìîäóëü äëÿ 32- è 64-áèòíîãî êîäà, ñîâìåñòèìûé ñ Win32- è Win64-êîìïèëÿòîðàìè Microsoft.
- aout â îáúåêòíûé ìîäóëü â âàðèàíòå ôîðìàòà a.out, èñïîëüçîâàâøåìñÿ â ðàííèõ Linux-ñèñòåìàõ.
- aoutb â âåðñèÿ ôîðìàòà a.out äëÿ BSD-ñîâìåñòèìûõ îïåðàöèîííûõ ñèñòåì.
- coff â îáúåêòíûé ìîäóëü â ôîðìàòå COFF, ñîâìåñòèìîì ñ êîìïîíîâùèêîì èç DJGPP.
- elf32 è elf64 â îáúåêòíûé ìîäóëü â ôîðìàòàõ ELF32 è ELF64, èñïîëüçóåìûõ â Linux è Unix System V, âêëþ÷àÿ Solaris x86, UnixWare è SCO Unix.
Ôîðìàò âûõîäíîãî ôàéëà ìîæíî çàäàòü ñ ïîìîùüþ êëþ÷à êîìàíäíîé ñòðîêè -f. Ôîðìàòû ìîãóò ðàñøèðÿòü ñèíòàêñèñ íåêîòîðûõ èíñòðóêöèé è äîáàâëÿòü ñîáñòâåííûå èíñòðóêöèè.
[ïðàâèòü] Ïðèìåðû ïðîãðàììû Hello, world! ïîä ðàçíûå ÎÑ
Ïðèìåðû ïðîãðàììû Hello, world!, êîòîðàÿ âûâîäèò ñîîòâåòñòâóþùåå ñîîáùåíèå è çàâåðøàåòñÿ.
SECTION .text org 0x100 ; ýòà äèðåêòèâà íóæíà òîëüêî â ñëó÷àå .com ôàéëà, â êîòîðîì íåò íèêàêèõ ñåêöèé mov ah, 0x9 mov dx, hello int 0x21 mov ax, 0x4c00 ; ah == 0x4c al == 0x00 int 0x21 SECTION .data hello DB "Hello, world!",0xd,0xa,'$'
%include 'WIN32N.INC' EXTERN MessageBoxA Import MessageBoxA user32.dll EXTERN ExitProcess Import ExitProcess kernel32.dll SECTION CODE USE32 CLASS=CODE ..start: push UINT MB_OK push LPCTSTR title push LPCTSTR banner push HWND NULL call [MessageBoxA] push UINT NULL call [ExitProcess] SECTION DATA USE32 CLASS=DATA banner db 'Hello, world!',0xD,0xA,0 title db 'Hello',0
; Hello.asm EXTERN MessageBoxW EXTERN ExitProcess SECTION .text USE64 start: sub rsp, 28h ; Microsoft x64 calling convention "shadow space" xor rcx, rcx ; HWND hWnd = NULL lea rdx, [banner] ; LPCTSTR lpText = banner lea r8, [title] ; LPCTSTR lpCaption = title xor r9, r9 ; UINT uType = MB_OK call MessageBoxW ; MessageBox(hWnd, lpText, lpCaption, uType) xor rcx, rcx ; UINT uExitCode = 0 call ExitProcess ; ExitProcess(uExitCode) SECTION .data banner dw __utf16__('Hello, world!'),0 title dw __utf16__('Hello!'),0
>nasm -f win64 Hello.asm
>golink Hello.obj kernel32.dll user32.dll
SECTION .data msg db "Hello, world!",0xa len equ $ - msg SECTION .text global _start ; the program entry point _start: mov eax, 4 ; 'write' syscall mov ebx, 1 ; file descr. 1 (stdout) mov ecx, msg ; pointer to the data mov edx, len ; amount of data int 0x80 ; call to the kernel mov eax, 1 ; '_exit' syscall mov ebx, 0 ; zero exit code (success) int 0x80 ; call to the kernel
SECTION .data msg db "Hello, world!",0xa len equ $ - msg SECTION .text global _start ; the program entry point _start: push dword len push dword msg push dword 1 ; 1 is the file descriptor of stdout mov eax, 4 ; 4 is the 'write' syscall push eax ; we must leave an extra dword on the stack int 0x80 ; call to the kernel add esp, 16 ; clean up the stack push dword 0 ; 0 is the exit code (success) mov eax, 1 ; 1 is the '_exit' syscall push eax ; extra dword on the stack int 0x80 ; call to the kernel ; no cleanup - we will never return
bits 32 %include 'mos.inc' section .text MOS_HEADER01 main,image_end,memory_end,stacktop,0,0 main: redraw: call draw_window wait_event: MOS_WAITEVENT dec eax jz redraw dec eax jz key ;button pressed; we have only one button, close MOS_EXIT key: ;key pressed, read it and ignore mov eax, MOS_SC_GETKEY int 0x40 jmp wait_event draw_window: MOS_STARTREDRAW xor eax, eax mov ebx, 10*65536 + 150 mov ecx, 40*65536 + 50 mov edx, 0x33FFFFFF mov edi, header int 0x40 ;define&draw window mov eax, MOS_SC_WRITETEXT mov ebx, 30*65536 + 10 mov ecx, 0x80000000 mov edx, string int 0x40 ;display string MOS_ENDREDRAW ret section .data header db 'HelloWorld test',0 string db 'Hello, World!',0 image_end: section .bss alignb 4 stack resb 1024 stacktop: memory_end:
[ïðàâèòü] Èçâåñòíûå ïðîãðàììû, íàïèñàííûå íà NASM
- Asmutils â íàáîð ñèñòåìíûõ óòèëèò äëÿ îïåðàöèîííûõ ñèñòåì BSD, UnixWare, Solaris è AtheOS.
- Ïðîåêò AsmOS[9] â îïåðàöèîííàÿ ñèñòåìà íà àññåìáëåðå NASM (ñåé÷àñ íà ñòàäèè ðàçðàáîòêè).
[ïðàâèòü] Ïðèìå÷àíèÿ
- â‘ 1.1 What Is NASM?. The Netwide Assembler: NASM. Îôèöèàëüíûé ñàéò. â «NASM, is an 80x86 and x86-64 assembler» Àðõèâèðîâàíî èç ïåðâîèñòî÷íèêà 18 ôåâðàëÿ 2012. Ïðîâåðåíî 14 èþëÿ 2010.
- â‘ Àññåìáëåðû äëÿ Linux: Ñðàâíåíèå GAS è NASM
- â‘ 1 2 Èñïîëüçîâàíèå àññåìáëåðà NASM â Windows
- â‘ 1 2 Ðýíäîëë Õàéä. Which Assembler is the Best? (àíãë.). Àðõèâèðîâàíî èç ïåðâîèñòî÷íèêà 18 ôåâðàëÿ 2012. Ïðîâåðåíî 18 èþëÿ 2010.
- â‘ Ïîääåðæêà Intel-ñèíòàêñèñà, âûçûâàåìîãî ÷åðåç ñïåöèàëüíóþ äèðåêòèâó
.intel_syntax, ïîÿâèëàñü â gas-2.10; ñì. gas/NEWS (àíãë.). Àðõèâèðîâàíî èç ïåðâîèñòî÷íèêà 18 ôåâðàëÿ 2012. Ïðîâåðåíî 18 èþëÿ 2010. - â‘ C.2.33 Version 0.98.09b with John Coffman patches released 28-Oct-2001. The Netwide Assembler: NASM. Appendix C: NASM Version History. Îôèöèàëüíûé ñàéò. Àðõèâèðîâàíî èç ïåðâîèñòî÷íèêà 18 ôåâðàëÿ 2012. Ïðîâåðåíî 18 èþëÿ 2010.
- â‘ Chapter 7: Output Formats. The Netwide Assembler: NASM. Îôèöèàëüíûé ñàéò. Àðõèâèðîâàíî èç ïåðâîèñòî÷íèêà 18 ôåâðàëÿ 2012. Ïðîâåðåíî 14 èþëÿ 2010.
- â‘ Èñïîëüçîâàíèå ðàçëè÷íûõ êîìïèëÿòîðîâ â ÊîëèáðèÎÑ
- â‘ Îïåðàöèîííàÿ ñèñòåìà íà àññåìáëåðå NASM
[ïðàâèòü] Ëèòåðàòóðà
- Ðóäîëüô Ìàðåê. Àññåìáëåð íà ïðèìåðàõ. Áàçîâûé êóðñ. â ÑÏá.: Íàóêà è òåõíèêà, 2005. â 240 ñ. â ISBN 5-94387-232-9
- À. Â. Ñòîëÿðîâ. Ïðîãðàììèðîâàíèå íà ÿçûêå àññåìáëåðà NASM äëÿ ÎÑ Unix. â Ì.: ÌÀÊÑ Ïðåññ, 2011. â 188 ñ. â ISBN 978-5-317-03627-0
[ïðàâèòü] Ññûëêè
- Îôèöèàëüíûé ñàéò
- Ïðîåêò NASM íà ñàéòå SourceForge.net
- Ðàñøèðåííûé àññåìáëåð: NASM
- Ââåäåíèå â NASM (íèçêîóðîâíåâîå ïðîãðàììèðîâàíèå äëÿ Windows)
Äëÿ óëó÷øåíèÿ ýòîé ñòàòüè æåëàòåëüíî?:
|
| ßçûê àññåìáëåðà | |
|---|---|
| IDE | |
| Òðàíñëÿòîðû | |
| Ôîðìàòû ñèíòàêñèñà | |

