When Masm is mentioned, then usually Masm v8.00 is meant, unless stated otherwise. Masm v8.00 also was the first Masm version supporting 64-bit (ML64.EXE).
The Masm documentation itself can be found on numerous places in the web, in plain text, HTML, PDF and Windows Help format. However, it's usually the documentation that came whith Masm v6.1, hence is a bit outdated.
Options are usually entered via the command line. Additionally, when starting, JWasm will search for environment variable JWASM and handle it similar to the way Masm handles variable ML. Hence it is also possible to enter options via this method.
The options specific to JWasm - and also the options which are handled somewhat differently by JWasm compared to Masm - will be handled in the following chapters.
|
The binary format is most useful for bootloaders or DOS COM files, but may be used to create any binary format. See sample Win32_5, that demonstrates how to use -bin for creating a Win32 application.
If a listing file is produced, a binary map will be added, which shows the file and memory layout of the image:
.model tiny .data 00000000 0D0A48656C6C6F2C20 str1 db 13,10,"Hello, world!",13,10,'$' 00000000 .code org 100h 00000100 start: 00000100 B409 mov ah, 09h 00000102 BA0000 mov dx, offset str1 00000105 CD21 int 21h 00000107 B8004C mov ax, 4c00h 0000010A CD21 int 21h end start Binary Map: Segment Pos(file) VA Size(fil) Size(mem) --------------------------------------------------------------- _TEXT 0 100 C C _DATA C 10C 12 12 --------------------------------------------------------------- 1E 1E
Use OPTION ELF to set values in the ELF header.
Use OPTION ELF to set values in the ELF header.
If JWlink is used, the <file_name> argument may be omitted. Then JWasm will write the import definitions directly into the object module's linker directive section (section ".drectve"). This works for output formats COFF and ELF only. See sample Win32_7 how to use JWasm and JWlink to create a Windows binary without import libs.
Option -win64 will also set cpu to x86-64, model to FLAT and default calling convention to FASTCALL. This is to make JWasm compatible with Masm64 (ML64.EXE).
With OPTION WIN64, parameters specific to Win64 may be set.
Option -zt0 will make object modules compatible to ALINK + Win32.lib.
The Microsoft FASTCALL convention uses registers AX, DX and BX in 16-bit for the first 3 parameters, and registers ECX and EDX in 32-bit for the first 2 parameters which are small enough to fit into a register.
The Open Watcom fastcall convention uses up to four registers ( E/AX, E/DX, E/BX, E/CX ).
In 64-bit mode, FASTCALL means the standard Windows 64 ABI if option -win64 was given and it is the default then. For -elf64, there is currently no FASTCALL support.
Example using back quotes:
Module 1:
`functionname.with.dots` PROC C PUBLIC a1:dword
Module 2:
`functionname.with.dots` PROTO C :dword .code INVOKE `functionname.with.dots`, 1
Since IDs in back quotes are not 100% compatible with "normal" IDs, it might be considered to use the ALIAS directive instead. Be aware that, since the alias handling is a linker task, it is necessary to define both names, the alias name and the target name, as public.
mov eax, 1.0
With type coercion, it's also possible to define a 64-bit "double", although it's probably useful in 64-bit code only:
mov rax, real8 ptr 1.0
Additionally, operators LOW32 and HIGH32 accept a floating-point constant as argument. In this case, the constant is assumed to have format REAL8. Thus it's possible to pass a double constant directly as a procedure argument in 32-bit code:
push HIGH32 1.0 push LOW32 1.0 call WorkWithReal8Value
Example:
.386 .model flat, stdcall option PROCALIGN:16 .code proc1 PROC ret proc1 endp proc2 PROC ret proc2 endp end
The listing shows that start address of proc2 is aligned to 16 (=10h):
00000000 proc1 PROC 00000000 ret 00000000 C3 * retn 00000001 proc1 endp 00000010 proc2 PROC 00000010 ret 00000010 C3 * retn 00000011 proc2 endp
Note: to ensure that the procedures are aligned in the final binary as it is supposed by the OPTION PROCALIGN value, the alignment of the current code segment must be at least the value of OPTION PROCALIGN.
start_fixups | offset within the header where segment fixups will start. The size of the header will always be at least this value, even if there are no fixups at all. Default - and minimum - value is 1Eh. |
header_align | alignment of the header (including segment fixups). Value must be a power of 2, 10h is the default and minimum. |
heap_min | the additional space (in paragraphs) which is needed by the binary to run. Default is the total of the sizes of the uninitialized BSS and STACK segments. |
heap_max | space (in paragraphs) which the binary would like to have. Default is FFFFh. |
|
The effects of setting this options are subtle and useful only for MS Windows applications: if the function described by the prototype is called via INVOKE, slightly more efficient code than normal is generated, because the function's address in the IAT is used. Example:
push NULL call DWORD PTR [_imp__GetModuleHandle@4]code generation without OPTION DLLIMPORT:
push NULL call _GetModuleHandle@4 ... _GetModuleHandle@4: jmp DWORD PTR [_imp__GetModuleHandle@4] ;stub added by the linker
.386 .model flat,stdcall option dllimport:<kernel32> GetModuleHandleA proto :dword ExitProcess proto :dword option dllimport:none .code invoke GetModuleHandleA, 0 invoke ExitProcess, 0 end
The .X64 directive isn't needed usually, because for output formats WIN64 (see -win64) and ELF64 (see -elf64), .X64 is the default.
The .X64p directive is useful for mixed-model binaries or system software (see example DOS64 ).
When the cpu is set to 64-bit, the SEGMENT directive accepts a new 'size' value: USE64. It tells the assembler that this segment's offset is 64-bit wide and uses 64-bit instructions.
The SYSCALL calling convention is renamed to SYSCALL_ when 64-bit is on, because there exists a SYSCALL instruction mnemonic in this mode.
<macro_name> MACRO <param_name>:LABEL [,<param_name>[, ...]]
<label> <macro_name> [<argument>, ...]
foo macro lbl:LABEL, first, second lbl db first dw second endm .data data1 foo 1,1000 data2 foo 2,2000Note that a code label ( that is, a label followed by a colon or double-colon ) is parsed BEFORE the macro is evaluated, hence such a label will have been defined already when the macro "runs".
IFDEF <struct_name>.<member_name>
vmm1 MMWORD 1122334455667788h vxmm1 XMMWORD 112233445566778899AABBCCDDEEFFhMasm will accept just floating-point initializers for data items of type [X]MMWORD. It's even worse, since floating-point initializers are silently ignored for data items with sizes != 4, 8 and 10; since XMMWORD has size 16, it's impossible to initialize such an item directly. JWasm copies this Masm behavior, but to allow to initialize a XMMWORD with a floating-point value, one may use type coercion:
vxmm1 XMMWORD real4 ptr 1.0 ;bytes 4-15 will be 0 vxmm2 XMMWORD real8 ptr 1.0 ;bytes 8-15 will be 0Variants that work in both JWasm and Masm, and also allow to initialize the full XMMWORD are:
vxmm1 LABEL XMMWORD real4 1.0, 2.0, 3.0, 4.0 vxmm2 LABEL XMMWORD real8 1.0, 2.0
Also see Member Argument for IF[N]DEF and .ERR[N]DEF Directives.
Since Masm v8, a PROTO or EXTERNDEF for a symbol which is later defined as a PROC will make the procedure public, no matter what a possible visibility attribute of the PROC itself - or the default one set with OPTION PROC - is telling.
OTOH, with Masm v6/7, both the visibility attribute of the PROC directive and the current default setting of OPTION PROC will affect ths symbol's visibility.
Masm6 Masm8 JWasm JWasm+Zv8 ------------------------------------- On,E,P x x On,E,Pn x x On,E,Pp x x x x Op,E,P x x x x Op,E,Pn x x x Op,E,Pp x x x x On = OPTION PROC:PRIVATE Op = OPTION PROC:PUBLIC E = PROTO or EXTERNDEF before PROC P = PROC without visibility attribute Pn = PROC with PRIVATE visibility attribute Pp = PROC with PUBLIC visibility attribute x = procedure will be publicAs default, JWasm more or less copies the Masm v6/7 behavior. The difference is that an explicite visibility attribute behind PROC has the highest priority for JWasm. However, since v2.04, there's an additional cmdline option -Zv8 which will make JWasm behave like Masm v8+.
It should be noted that without a PROTO/EXTERNDEF before PROC, there are no differences between Masm v6, v8 and JWasm, and the -Zv8 switch also has no effect then.
Since JWasm v2.06, instruction set AVX is supported. ( With Masm, these instructions require Masm v10 ).
For a few instructions, the encoding differs between Masm versions.
Example:
cmp al,dlis encoded 38 D0 in Masm v6, but 3A C2 in Masm v8. In such cases, JWasm will prefer to copy the encoding of Masm v8.
Label1: JMP Label2 Label2: REPEAT Label2 - Label1 INC AX ENDMMasm will - incorrectly - repeat the loop 10 times, although the result of expression Label2 - Label1 is 2 only. OTOH, JWasm will repeat the loop 2 times only, because it's using an "optimistic" strategy concerning forward references.
The big disadvantage is that using the FRAME keyword in Masm "disables" most of the other high level features combined with PROC (function parameters, locals and registers saved with USES) because no function prologues and epilogues are generated anymore. Additionally, the implementation in some Masm versions seems to be a bit buggy. Because of this and to ease the usage of SEH in Win64 there is a new directive implemented in JWasm:
OPTION FRAME:AUTO
If this option is set, JWasm will create Win64 SEH-compatible prologues and epilogues. If the option is off, JWasm will behave Masm-compatible, that is, FRAME found in a PROC directive will disable automatic prologue/epilogue generation. See sample Win64_3e how this option is supposed to be used.
As for the PROC syntax: The Masm documentation states that FRAME can be used in combination with USES and procedure parameters and must be located behind all parameters. However, this syntax isn't accepted by any Masm version. The only syntax which Masm will accept without being confused is FRAME as the one and only parameter for PROC. Therefore JWasm doesn't follow the Masm documentation in this point: the optional FRAME keyword is expected *before* the procedure parameters. The syntax in JWasm is:
procname PROC [public] FRAME[:exc_handler] [USES <reglist>] [parameters]The SEH "primitives" will generate some additional data in segments .pdata and .xdata. This data is somewhat hidden, but JWasm will display the corresponding data definitions in the listing if option -Sg is set.
This manual was written by Andreas Grech ( aka Japheth ).
It may be redistributed as long as it is free of charge.
|
8-bit registers | SPL | BPL | SIL | DIL | ||||
R8B | R9B | R10B | R11B | R12B | R13B | R14B | R15B | |
16-bit registers | R8W | R9W | R10W | R11W | R12W | R13W | R14W | R15W |
32-bit registers | R8D | R9D | R10D | R11D | R12D | R13D | R14D | R15D |
64-bit registers | RAX | RCX | RDX | RBX | RSP | RBP | RSI | RDI |
R8 | R9 | R10 | R11 | R12 | R13 | R14 | R15 | |
SSE registers | XMM8 | XMM9 | XMM10 | XMM11 | XMM12 | XMM13 | XMM14 | XMM15 |
AVX registers | YMM8 | YMM9 | YMM10 | YMM11 | YMM12 | YMM13 | YMM14 | YMM15 |
Control registers | CR8 |
|
|
|
|
|
|
;--- This sample shows how to use SEH primitives. It doesn't use hll ;--- directives. Thus this source can be assembled by both JWasm ;--- and Masm64. ;--- ;--- to assemble enter: ;--- JWasm -win64 Win64_3.asm ;--- or: ;--- ml64 -c Win64_3.asm ;--- ;--- to link the binary enter: ;--- Link Win64_3.obj option casemap:none includelib kernel32.lib includelib user32.lib HINSTANCE typedef QWORD HWND typedef QWORD HMENU typedef QWORD HICON typedef QWORD HBRUSH typedef QWORD HCURSOR typedef QWORD WPARAM typedef QWORD LPARAM typedef QWORD LPSTR typedef QWORD LPVOID typedef QWORD UINT typedef DWORD NULL equ 0 WS_OVERLAPPEDWINDOW equ 0CF0000h CW_USEDEFAULT equ 80000000h SW_SHOWDEFAULT equ 10 SW_SHOWNORMAL equ 1 IDC_ARROW equ 32512 IDI_APPLICATION equ 32512 WM_DESTROY equ 2 CS_VREDRAW equ 1 CS_HREDRAW equ 2 COLOR_WINDOW equ 5 proto_WNDPROC typedef proto :HWND,:QWORD,:WPARAM,:LPARAM WNDPROC typedef ptr proto_WNDPROC WNDCLASSEXA struct 8 cbSize DWORD ? style DWORD ? lpfnWndProc WNDPROC ? cbClsExtra DWORD ? cbWndExtra DWORD ? hInstance HINSTANCE ? hIcon HICON ? hCursor HCURSOR ? hbrBackground HBRUSH ? lpszMenuName LPSTR ? lpszClassName LPSTR ? hIconSm HICON ? WNDCLASSEXA ends POINT struct x SDWORD ? y SDWORD ? POINT ends MSG struct 8 hwnd HWND ? message DWORD ? wParam WPARAM ? lParam LPARAM ? time DWORD ? pt POINT <> MSG ends GetModuleHandleA proto :LPSTR GetCommandLineA proto ExitProcess proto :UINT LoadIconA proto :HINSTANCE, :LPSTR LoadCursorA proto :HINSTANCE, :LPSTR RegisterClassExA proto :ptr WNDCLASSEXA CreateWindowExA proto :DWORD, :LPSTR, :LPSTR, :DWORD, :SDWORD, :SDWORD, :SDWORD, :SDWORD, :HWND, :HMENU, :HINSTANCE, :LPVOID ShowWindow proto :HWND, :SDWORD UpdateWindow proto :HWND GetMessageA proto :ptr MSG, :HWND, :SDWORD, :SDWORD TranslateMessage proto :ptr MSG DispatchMessageA proto :ptr MSG PostQuitMessage proto :SDWORD DefWindowProcA proto :HWND, :UINT, :WPARAM, :LPARAM ;WinMain proto :HINSTANCE, :HINSTANCE, :LPSTR, :UINT .data ClassName db "SimpleWinClass",0 AppName db "Our First Window",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? .code WinMainCRTStartup proc FRAME push rbp .pushreg rbp mov rbp,rsp .setframe rbp, 0 .endprolog sub rsp,32 mov ecx,NULL call GetModuleHandleA mov hInstance, rax call GetCommandLineA mov CommandLine, rax mov rcx, hInstance mov rdx, NULL mov r8, CommandLine mov r9d, SW_SHOWDEFAULT call WinMain mov ecx, eax call ExitProcess align 4 WinMainCRTStartup endp WinMain proc FRAME push rbp .pushreg rbp mov rbp,rsp .setframe rbp, 0 .endprolog sub rsp, sizeof WNDCLASSEXA + sizeof MSG + sizeof HWND + 12*8 hInst equ <[rbp+10h]> hPrevInst equ <[rbp+18h]> CmdLine equ <[rbp+20h]> CmdShow equ <[rbp+28h]> wc equ <[rbp - sizeof WNDCLASSEXA].WNDCLASSEXA> msg equ <[rbp - sizeof WNDCLASSEXA - sizeof MSG].MSG> hwnd equ <[rbp - sizeof WNDCLASSEXA - sizeof MSG - sizeof HWND]> mov hInst, rcx ;store param1 in shadow space mov wc.cbSize, SIZEOF WNDCLASSEXA mov wc.style, CS_HREDRAW or CS_VREDRAW ; mov rax, OFFSET WndProc ;using LEA is preferable lea rax, [WndProc] mov wc.lpfnWndProc, rax mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL mov wc.hInstance, rcx mov wc.hbrBackground, COLOR_WINDOW+1 mov wc.lpszMenuName, NULL ; mov rax, OFFSET ClassName ;using LEA is preferable lea rax, [ClassName] mov wc.lpszClassName, rax mov ecx, NULL mov edx, IDI_APPLICATION call LoadIconA mov wc.hIcon, rax mov wc.hIconSm, rax mov ecx, NULL mov edx, IDC_ARROW call LoadCursorA mov wc.hCursor,rax lea rcx, wc call RegisterClassExA mov ecx, NULL lea rdx, [ClassName] lea r8, [AppName] mov r9d, WS_OVERLAPPEDWINDOW mov dword ptr [rsp+4*8], CW_USEDEFAULT mov dword ptr [rsp+5*8], CW_USEDEFAULT mov dword ptr [rsp+6*8], CW_USEDEFAULT mov dword ptr [rsp+7*8], CW_USEDEFAULT mov qword ptr [rsp+8*8], NULL mov qword ptr [rsp+9*8], NULL mov rax, hInst mov [rsp+10*8], rax mov qword ptr [rsp+11*8], NULL call CreateWindowExA mov hwnd,rax mov rcx, hwnd mov edx, SW_SHOWNORMAL call ShowWindow mov rcx, hwnd call UpdateWindow ;--- message loop @@: lea rcx, msg mov rdx, NULL mov r8, 0 mov r9, 0 call GetMessageA and rax, rax jz @F lea rcx, msg call TranslateMessage lea rcx, msg call DispatchMessageA jmp @B @@: mov rax, msg.wParam add rsp, sizeof WNDCLASSEXA + sizeof MSG + sizeof HWND + 12*8 pop rbp ret align 4 WinMain endp WndProc proc FRAME sub rsp, 4*8 .allocstack 4*8 .endprolog cmp edx, WM_DESTROY jnz @F mov ecx, NULL call PostQuitMessage xor rax,rax jmp exit @@: call DefWindowProcA exit: add rsp, 4*8 ret align 4 WndProc endp end |
;--- SEH support in Win64. Unlike Win64_3, ;--- this version uses hll directives, so it cannot be assembled ;--- with Masm64. Also, OPTION FRAME:AUTO is used. ;--- ;--- to create the binary enter: ;--- JWasm -win64 Win64_3e.asm ;--- Link Win64_3e.obj option casemap:none option frame:auto ;generate SEH-compatible prologues and epilogues includelib kernel32.lib includelib user32.lib HINSTANCE typedef QWORD HWND typedef QWORD HMENU typedef QWORD HICON typedef QWORD HBRUSH typedef QWORD HCURSOR typedef QWORD WPARAM typedef QWORD LPARAM typedef QWORD LPSTR typedef QWORD LPVOID typedef QWORD UINT typedef DWORD NULL equ 0 WS_OVERLAPPEDWINDOW equ 0CF0000h CW_USEDEFAULT equ 80000000h SW_SHOWDEFAULT equ 10 SW_SHOWNORMAL equ 1 IDC_ARROW equ 32512 IDI_APPLICATION equ 32512 WM_DESTROY equ 2 CS_VREDRAW equ 1 CS_HREDRAW equ 2 COLOR_WINDOW equ 5 proto_WNDPROC typedef proto :HWND,:QWORD,:WPARAM,:LPARAM WNDPROC typedef ptr proto_WNDPROC WNDCLASSEXA struct 8 cbSize DWORD ? style DWORD ? lpfnWndProc WNDPROC ? cbClsExtra DWORD ? cbWndExtra DWORD ? hInstance HINSTANCE ? hIcon HICON ? hCursor HCURSOR ? hbrBackground HBRUSH ? lpszMenuName LPSTR ? lpszClassName LPSTR ? hIconSm HICON ? WNDCLASSEXA ends POINT struct x SDWORD ? y SDWORD ? POINT ends MSG struct 8 hwnd HWND ? message DWORD ? wParam WPARAM ? lParam LPARAM ? time DWORD ? pt POINT <> MSG ends GetModuleHandleA proto :LPSTR GetCommandLineA proto ExitProcess proto :UINT LoadIconA proto :HINSTANCE, :LPSTR LoadCursorA proto :HINSTANCE, :LPSTR RegisterClassExA proto :ptr WNDCLASSEXA CreateWindowExA proto :DWORD, :LPSTR, :LPSTR, :DWORD, :SDWORD, :SDWORD, :SDWORD, :SDWORD, :HWND, :HMENU, :HINSTANCE, :LPVOID ShowWindow proto :HWND, :SDWORD UpdateWindow proto :HWND GetMessageA proto :ptr MSG, :HWND, :SDWORD, :SDWORD TranslateMessage proto :ptr MSG DispatchMessageA proto :ptr MSG PostQuitMessage proto :SDWORD DefWindowProcA proto :HWND, :UINT, :WPARAM, :LPARAM WinMain proto :HINSTANCE, :HINSTANCE, :LPSTR, :UINT .data ClassName db "SimpleWinClass",0 AppName db "Our First Window",0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? .code WinMainCRTStartup proc FRAME invoke GetModuleHandleA, NULL mov hInstance, rax invoke GetCommandLineA mov CommandLine, rax invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT invoke ExitProcess, eax WinMainCRTStartup endp WinMain proc FRAME hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:UINT local wc:WNDCLASSEXA local msg:MSG local hwnd:HWND mov hInst, rcx mov wc.cbSize, SIZEOF WNDCLASSEXA mov wc.style, CS_HREDRAW or CS_VREDRAW lea rax, [WndProc] mov wc.lpfnWndProc, rax mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL mov wc.hInstance, rcx mov wc.hbrBackground, COLOR_WINDOW+1 mov wc.lpszMenuName, NULL lea rax, [ClassName] mov wc.lpszClassName, rax invoke LoadIconA, NULL, IDI_APPLICATION mov wc.hIcon, rax mov wc.hIconSm, rax invoke LoadCursorA, NULL, IDC_ARROW mov wc.hCursor,rax invoke RegisterClassExA, addr wc invoke CreateWindowExA, NULL, ADDR ClassName, ADDR AppName,\ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,\ CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL, NULL,\ hInst, NULL mov hwnd,rax invoke ShowWindow, hwnd, SW_SHOWNORMAL invoke UpdateWindow, hwnd .while (1) invoke GetMessageA, ADDR msg, NULL, 0, 0 .break .if (!rax) invoke TranslateMessage, ADDR msg invoke DispatchMessageA, ADDR msg .endw mov rax, msg.wParam ret WinMain endp WndProc proc FRAME hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .if ( edx == WM_DESTROY ) invoke PostQuitMessage, NULL xor rax,rax .else invoke DefWindowProcA, rcx, edx, r8, r9 .endif ret WndProc endp end WinMainCRTStartup |
;--- DOS program which switches to long-mode and back. ;--- Note: requires at least JWasm v2. ;--- Also: needs a 64bit cpu in real-mode to run. ;--- Parts of the source are based on samples supplied by ;--- sinsi and Tomasz Grysztar in the FASM forum. ;--- To create the binary enter: ;--- JWasm -mz DOS64.asm .x64p ;--- 16bit start/exit code _TEXT16 segment use16 para public 'CODE' assume ds:_TEXT16 assume es:_TEXT16 GDTR label fword ; Global Descriptors Table Register dw 4*8-1 ; limit of GDT (size minus one) dd offset GDT ; linear address of GDT IDTR label fword ; Interrupt Descriptor Table Register dw 256*16-1 ; limit of IDT (size minus one) dd 0 ; linear address of IDT nullidt label fword dw 3FFh dd 0 align 8 GDT dq 0 ; null descriptor dw 0FFFFh,0,9A00h,0AFh ; 64-bit code descriptor dw 0FFFFh,0,9A00h,000h ; compatibility mode code descriptor dw 0FFFFh,0,9200h,000h ; compatibility mode data descriptor wPICMask dw 0 ; variable to save/restore PIC masks start16: push cs pop ds mov ax,cs movzx eax,ax shl eax,4 add dword ptr [GDTR+2], eax ; convert offset to linear address mov word ptr [GDT+2*8+2], ax mov word ptr [GDT+3*8+2], ax shr eax,16 mov byte ptr [GDT+2*8+4], al mov byte ptr [GDT+3*8+4], al mov ax,ss mov dx,es sub ax,dx mov bx,sp shr bx,4 add bx,ax mov ah,4Ah int 21h ; free unused memory push cs pop es mov ax,ss mov dx,cs sub ax,dx shl ax,4 add ax,sp push ds pop ss mov sp,ax ; make a TINY model, CS=SS=DS=ES smsw ax test al,1 jz @F mov dx,offset err1 mov ah,9 int 21h mov ah,4Ch int 21h err1 db "Mode is V86. Need REAL mode to switch to LONG mode!",13,10,'$' @@: xor edx,edx mov eax,80000001h ; test if long-mode is supported cpuid test edx,20000000h jnz @F mov dx,offset err2 mov ah,9 int 21h mov ah,4Ch int 21h err2 db "No 64bit cpu detected.",13,10,'$' @@: mov bx,1000h mov ah,48h int 21h jnc @F mov dx,offset err3 mov ah,9 int 21h mov ah,4Ch int 21h err3 db "Out of memory",13,10,'$' @@: add ax,100h-1 ; align to page boundary mov al,0 mov es,ax ;--- setup page directories and tables sub di,di mov cx,4096 sub eax,eax rep stosd ; clear 4 pages sub di,di mov ax,es movzx eax,ax shl eax,4 mov cr3,eax ; load page-map level-4 base lea edx, [eax+5000h] mov dword ptr [IDTR+2], edx or eax,111b add eax, 1000h mov es:[di+0000h],eax ; first PDP table add eax, 1000h mov es:[di+1000h],eax ; first page directory add eax, 1000h mov es:[di+2000h],eax ; first page table mov di,3000h ; address of first page table mov eax,0 + 111b mov cx,256 ; number of pages to map (1 MB) @@: stosd add di,4 add eax,1000h loop @B ;--- setup ebx/rbx with linear address of _TEXT mov bx,_TEXT movzx ebx,bx shl ebx,4 add [llg], ebx ;--- create IDT mov di,5000h mov cx,32 mov edx, offset exception add edx, ebx make_exc_gates: mov eax,edx stosw mov ax,8 stosw mov ax,8E00h stosd xor eax, eax stosd stosd add edx,4 loop make_exc_gates mov cx,256-32 make_int_gates: mov eax,offset interrupt add eax, ebx stosw mov ax,8 stosw mov ax,8E00h stosd xor eax, eax stosd stosd loop make_int_gates mov di,5000h mov eax, ebx add eax, offset clock mov es:[di+80h*16+0],ax ; set IRQ 0 handler shr eax,16 mov es:[di+80h*16+6],ax mov eax, ebx add eax, offset keyboard mov es:[di+81h*16+0],ax ; set IRQ 1 handler shr eax,16 mov es:[di+81h*16+6],ax ;--- clear NT flag pushf pop ax and ah,0BFh push ax popf ;--- reprogram PIC: change IRQ 0-7 to INT 80h-87h, IRQ 8-15 to INT 88h-8Fh cli in al,0A1h mov ah,al in al,21h mov [wPICMask],ax mov al,10001b ; begin PIC 1 initialization out 20h,al mov al,10001b ; begin PIC 2 initialization out 0A0h,al mov al,80h ; IRQ 0-7: interrupts 80h-87h out 21h,al mov al,88h ; IRQ 8-15: interrupts 88h-8Fh out 0A1h,al mov al,100b ; slave connected to IRQ2 out 21h,al mov al,2 out 0A1h,al mov al,1 ; Intel environment, manual EOI out 21h,al out 0A1h,al in al,21h mov al,11111100b ; enable only clock and keyboard IRQ out 21h,al in al,0A1h mov al,11111111b out 0A1h,al mov eax,cr4 or eax,1 shl 5 mov cr4,eax ; enable physical-address extensions (PAE) mov ecx,0C0000080h ; EFER MSR rdmsr or eax,1 shl 8 ; enable long mode wrmsr lgdt [GDTR] lidt [IDTR] mov cx,ss movzx ecx,cx ; get base of SS shl ecx,4 movzx esp,sp add ecx, esp ; ECX=linear address of current SS:ESP mov eax,cr0 or eax,80000001h mov cr0,eax ; enable paging + pmode db 66h, 0EAh ; jmp 0008:oooooooo llg dd offset long_start dw 8 ;--- switch back to real-mode and exit backtoreal: cli mov eax,cr0 and eax,7FFFFFFFh ; disable paging mov cr0,eax mov ecx,0C0000080h ; EFER MSR rdmsr and ah,not 1h ; disable long mode (EFER.LME=0) wrmsr mov ax,24 ; set SS,DS and ES to 64k data mov ss,ax mov ds,ax mov es,ax mov eax,cr0 ; switch to real mode and al,0FEh mov cr0, eax db 0eah ; clear instruction cache, CS=real-mode seg dw $+4 dw _TEXT16 mov ax,STACK ; SS=real-mode seg mov ss, ax mov sp,4096 push cs ; DS=real-mode _TEXT16 seg pop ds lidt [nullidt] ; IDTR=real-mode compatible values mov eax,cr4 and al,not 20h ; disable physical-address extensions (PAE) mov cr4,eax ;--- reprogram PIC: change IRQ 0-7 to INT 08h-0Fh, IRQ 8-15 to INT 70h-77h mov al,10001b ; begin PIC 1 initialization out 20h,al mov al,10001b ; begin PIC 2 initialization out 0A0h,al mov al,08h ; IRQ 0-7: back to ints 8h-Fh out 21h,al mov al,70h ; IRQ 8-15: back to ints 70h-77h out 0A1h,al mov al,100b ; slave connected to IRQ2 out 21h,al mov al,2 out 0A1h,al mov al,1 ; Intel environment, manual EOI out 21h,al out 0A1h,al in al,21h mov ax,[wPICMask] ; restore PIC masks out 21h,al mov al,ah out 0A1h,al sti mov ax,4c00h int 21h _TEXT16 ends ;--- here's the 64bit code segment. ;--- since 64bit code is always flat but the DOS mz format is segmented, ;--- there are restrictions, because the assembler doesn't know the ;--- linear address where the 64bit segment will be loaded: ;--- + direct addressing with constants isn't possible (mov [0B8000h],rax) ;--- since the rip-relative address will be calculated wrong. ;--- + 64bit offsets (mov rax, offset <var>) must be adjusted by the linear ;--- address where the 64bit segment was loaded (is in rbx). ;--- ;--- rbx must preserve linear address of _TEXT _TEXT segment para use64 public 'CODE' assume ds:FLAT, es:FLAT long_start: xor eax,eax mov ss,eax mov esp,ecx sti ; now interrupts can be used call WriteStrX db "Hello 64bit",10,0 nextcmd: mov r8b,0 ; r8b will be filled by the keyboard irq routine nocmd: cmp r8b,0 jz nocmd cmp r8b,1 ; ESC? jz esc_pressed cmp r8b,13h ; 'r'? jz r_pressed call WriteStrX db "unknown key ",0 mov al,r8b call WriteB call WriteStrX db 10,0 jmp nextcmd ;--- 'r' key: display some register contents r_pressed: call WriteStrX db 10,"cr0=",0 mov rax,cr0 call WriteQW call WriteStrX db 10,"cr2=",0 mov rax,cr2 call WriteQW call WriteStrX db 10,"cr3=",0 mov rax,cr3 call WriteQW call WriteStrX db 10,"cr4=",0 mov rax,cr4 call WriteQW call WriteStrX db 10,"cr8=",0 mov rax,cr8 call WriteQW call WriteStrX db 10,0 jmp nextcmd ;--- ESC: back to real-mode esc_pressed: jmp [bv] bv label fword dd offset backtoreal dw 16 ;--- screen output helpers ;--- scroll screen up one line ;--- rsi = linear address start of last line ;--- rbp = linear address of BIOS area (0x400) scroll_screen: cld mov edi,esi movzx eax,word ptr [rbp+4Ah] push rax lea rsi, [rsi+2*rax] mov cl, [rbp+84h] mul cl mov ecx,eax rep movsw pop rcx mov ax,0720h rep stosw ret WriteChr: push rbp push rdi push rsi push rbx push rcx push rdx push rax mov edi,0B8000h mov ebp,400h cmp byte ptr [rbp+63h],0B4h jnz @F xor di,di @@: movzx ebx, word ptr [rbp+4Eh] add edi, ebx movzx ebx, byte ptr [rbp+62h] mov esi, edi movzx ecx, byte ptr [rbx*2+rbp+50h+1] ;ROW movzx eax, word ptr [rbp+4Ah] mul ecx movzx edx, byte ptr [rbx*2+rbp+50h] ;COL add eax, edx mov dh,cl lea edi, [rdi+rax*2] mov al, [rsp] cmp al, 10 jz newline mov [rdi], al mov byte ptr [rdi+1], 07 inc dl cmp dl, byte ptr [rbp+4Ah] jb @F newline: mov dl, 00 inc dh cmp dh, byte ptr [rbp+84h] jbe @F dec dh call scroll_screen @@: mov [rbx*2+rbp+50h],dx pop rax pop rdx pop rcx pop rbx pop rsi pop rdi pop rbp ret WriteStr: ;write string in rdx push rsi mov rsi, rdx cld @@: lodsb and al,al jz @F call WriteChr jmp @B @@: pop rsi ret WriteStrX: ;write string at rip push rsi mov rsi, [rsp+8] cld @@: lodsb and al,al jz @F call WriteChr jmp @B @@: mov [rsp+8],rsi pop rsi ret WriteQW: ;write QWord in rax push rax shr rax,32 call WriteDW pop rax WriteDW: push rax shr rax,16 call WriteW pop rax WriteW: push rax shr rax,8 call WriteB pop rax WriteB: ;write Byte in al push rax shr rax,4 call WriteNb pop rax WriteNb: and al,0Fh add al,'0' cmp al,'9' jbe @F add al,7 @@: jmp WriteChr ;--- exception handler exception: excno = 0 repeat 32 push excno jmp @F excno = excno+1 endm @@: call WriteStrX db 10,"Exception ",0 pop rax call WriteB call WriteStrX db " errcode=",0 mov rax,[rsp+0] call WriteQW call WriteStrX db " rip=",0 mov rax,[rsp+8] call WriteQW call WriteStrX db 10,0 @@: jmp $ ;--- clock and keyboard interrupts clock: push rbp mov ebp,400h inc dword ptr [rbp+6Ch] pop rbp interrupt: ; handler for all other interrupts push rax mov al,20h out 20h,al pop rax iretq keyboard: push rax in al,60h test al,80h jnz @F mov r8b, al @@: in al,61h ; give finishing information out 61h,al ; to keyboard... mov al,20h out 20h,al ; ...and interrupt controller pop rax iretq _TEXT ends ;--- 4k stack, used in both modes STACK segment use16 para stack 'STACK' db 4096 dup (?) STACK ends end start16 |
;--- Win32 "hello world" console application. ;--- Uses JWasm's bin output format, so no linker needed. ;--- assemble: JWasm -bin -Fo Win32_5.exe Win32_5.ASM .386 option casemap:none .nolist include winnt.inc ;include PE image definitions .list STD_OUTPUT_HANDLE equ -11 IMAGEBASE equ 400000h PEHDR segment dword FLAT ;--- define the DOS "MZ" header org IMAGEBASE IMAGE_DOS_HEADER <"ZM", 80h, 1, 0,4,0,-1,0,200h,0,0,0,0,0,<0>,0,0,<0>,IMAGEREL PEHdr> db 0Eh ;push cs db 1Fh ;pop ds db 0BAh,0Eh,0 ;mov dx,text db 0B4h,09h ;mov ah,9 db 0CDh,21h ;int 21h db 0B8h,01h,4Ch;mov ax,4c01h db 0CDh,21h ;int 21h db "This program cannot be run in DOS mode",13,10,'$' org IMAGEBASE+80h ;--- define the Win32 "PE" header PEHdr label byte db "PE",0,0 IMAGE_FILE_HEADER <IMAGE_FILE_MACHINE_I386, num_sections, 0, 0, 0, sizeof IMAGE_OPTIONAL_HEADER32, IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LOCAL_SYMS_STRIPPED> IMAGE_OPTIONAL_HEADER32 { 10Bh, ;magic 6,0, ;linker major, minor 1000h,1000h,0, ;sizeof code, initialized data, uninitialized data IMAGEREL mainCRTStartup, ;entry point IMAGEREL start_text, IMAGEREL start_rdata, ;baseof code, data IMAGEBASE, ;imagebase 1000h,200h, ;section alignment, file alignment 4,0, ;OS major, minor 0,0, ;Image major, minor 4,0, ;Subsys major, minor 0, ;win32 version 3000h, ;sizeof image 1000h, ;sizeof header 0, ;checksum IMAGE_SUBSYSTEM_WINDOWS_CUI, 0, ;dll characteristics 100000h,1000h,;stack res,com 100000h,1000h,;heap res, com 0, ;loader flags 16, ;number of directories <<0,0>, ;exports < IMAGEREL start_idata, SECTIONREL endof_idata >, ;imports <0,0>,<0,0>, ;resource, exception <>,<>,<>,<>, ;security, baserelocs, debug, architecture <>,<>,<>,<>, ;globalptr, tls, load_config, bound_import <>,<>,<>,<>>} ;iat, delay_import, com descriptor, reserved ;--- define the section table sectiontable label byte IMAGE_SECTION_HEADER <".text", <sizeof_text>, IMAGEREL start_text, sizeof_text, 200h, 0, 0, 0, 0, 060000020h > IMAGE_SECTION_HEADER <".rdata", <SECTIONREL endof_idata + sizeof_const>, IMAGEREL start_rdata, SECTIONREL endof_idata + sizeof_const, 400h, 0, 0, 0, 0, 040000040h > num_sections equ ( $ - sectiontable ) / sizeof IMAGE_SECTION_HEADER org IMAGEBASE+200h ;forces physical size of header to 200h and sets VA to 400200h PEHDR ends ;--- the ALIGNx segments are needed because ;--- section alignment and file alignment are different ALIGN1 segment dword public FLAT 'DATA' org 0E00h ; change pc to RVA 1000h ALIGN1 ends _TEXT segment dword public FLAT 'CODE' _TEXT ends ALIGN2 segment dword public FLAT 'DATA' org 0E00h ; change pc to RVA 2000h ALIGN2 ends _IDATA segment dword public FLAT 'DATA' start_rdata label byte start_idata label byte ;--- import descriptors go here _IDATA ends _IDATA$1 segment dword public FLAT 'DATA' IMAGE_IMPORT_DESCRIPTOR <<0>,0,0,0,0> ;--- ILT entries go here _IDATA$1 ends _IDATA$2 segment dword public FLAT 'DATA' dd 0 ;--- end of last ILT ;--- IAT entries go here _IDATA$2 ends _IDATA$3 segment dword public FLAT 'DATA' dd 0 ;--- end of last IAT ;--- import name strings go here _IDATA$3 ends _IDATA$4 segment dword public FLAT 'DATA' endof_idata equ $ _IDATA$4 ends CONST segment dword public FLAT 'DATA' start_const label byte CONST ends DefineImpDll macro name _IDATA segment IMAGE_IMPORT_DESCRIPTOR <<IMAGEREL name&ILT>,0,0,IMAGEREL name, IMAGEREL name&IAT> _IDATA ends _IDATA$1 segment ifdef ImportDefined dd 0 ;terminate previous ILT endif name&ILT label dword _IDATA$1 ends _IDATA$2 segment ifdef ImportDefined dd 0 ;terminate previous IAT endif name&IAT label dword _IDATA$2 ends _IDATA$3 segment name db @CatStr(!",name, !"),0 align 4 _IDATA$3 ends ImportDefined equ 1 endm DefineImport macro name _IDATA$1 segment dd IMAGEREL n&name _IDATA$1 ends _IDATA$2 segment lp&name typedef ptr pr&name name lp&name IMAGEREL n&name _IDATA$2 ends _IDATA$3 segment n&name dw 0 db @CatStr(!",name, !"),0 align 4 _IDATA$3 ends endm prWriteConsoleA typedef proto stdcall :dword, :dword, :dword, :dword, :dword prGetStdHandle typedef proto stdcall :dword prExitProcess typedef proto stdcall :dword DefineImpDll kernel32 DefineImport ExitProcess DefineImport WriteConsoleA DefineImport GetStdHandle if 0 ;if further dlls are to be imported prMessageBoxA typedef proto stdcall :dword, :dword, :dword, :dword DefineImpDll user32 DefineImport MessageBoxA endif CONST segment string db 13,10,"hello, world.",13,10 sizeof_const equ $ - start_const CONST ends _TEXT segment assume ds:FLAT,es:FLAT start_text label near ;--- start of program main proc local dwWritten:dword local hConsole:dword invoke GetStdHandle, STD_OUTPUT_HANDLE mov hConsole,eax invoke WriteConsoleA, hConsole, addr string, sizeof string, addr dwWritten, 0 xor eax,eax ret main endp ;--- entry mainCRTStartup proc c invoke main invoke ExitProcess, eax mainCRTStartup endp sizeof_text equ $ - start_text org 200h ;align size of _TEXT to next 512 byte boundary _TEXT ends end |
;--- Win32_7 - Shows how to use OPTION DLLIMPORT and switch -Fd. ;--- No import libraries are needed in the link step. ;--- ;--- assemble: JWasm -coff -Fd Win32_7.ASM ;--- link: JWlink format windows pe f Win32_7.OBJ .386 .model FLAT, stdcall option casemap:none STD_OUTPUT_HANDLE equ -11 option dllimport:<kernel32> WriteConsoleA proto :dword, :dword, :dword, :dword, :dword GetStdHandle proto :dword ExitProcess proto :dword option dllimport:<user32> MessageBoxA proto :dword, :dword, :dword, :dword option dllimport:<none> .const msg db 13,10,"hello, world.",13,10 db 0 .code main proc local written:dword invoke GetStdHandle, STD_OUTPUT_HANDLE mov ebx, eax invoke WriteConsoleA, ebx, addr msg, sizeof msg, addr written, 0 invoke MessageBoxA, 0, addr msg, 0, 0 ret main endp ;--- entry start: invoke main invoke ExitProcess, 0 end start |
x029 | Multiple base registers not allowed | ||
x030 | Instruction or register not accepted in current CPU mode | ||
x031 | Invalid addressing mode with current CPU setting | ||
x032 | Cannot use TRn-TRn with current CPU setting | The TRx special registers were restricted to 80386 and 80486 cpus. | |
x033 | Must be index or base register | ||
x034 | Multiple index registers not allowed | ||
x035 | |||
x036 | Scale factor must be 1, 2, 4 or 8 | ||
x037 | Cannot be used as index register: <register> | Index registers are restricted. In 16-bit mode, only SI and DI can be index registers. In 32-bit mode, all general-purpose registers except ESP can be index registers. | |
x038 | Base and index register differ in size | ||
x039 | Expecting comma | ||
x040 | ORG needs a constant or local offset | ||
x041 | POP CS is not allowed | ||
x042 | Only MOV can use special register | The special registers CRx, DRx and TRx can only be moved to/from general purpose registers. | |
x043 | Cannot use SHORT with CALL | Distance of CALL operands must be NEAR or FAR. | |
x044 | Only SHORT jump distance is allowed | Some jump instructions accept short distances only (JCXZ, JECXZ, LOOPx). | |
x045 | Syntax error | ||
x046 | Prefix must be followed by an instruction | ||
x047 | Syntax error: Unexpected colon | ||
x048 | Operands must be the same size: <size op1> - <size op2> | ||
x049 | Invalid instruction operands | ||
x050 | |||
x051 | Immediate data out of range | ||
x052 | Can not use short or near modifiers with this instruction | ||
x053 | Jump out of range by <num> byte(s) | A short distance must be in the range -128 to +127. | |
x054 | Displacement out of range: <displacement> | ||
x055 | Initializer value too large | ||
x056 | Symbol already defined: <symbol> | ||
x057 | Offset magnitude too large for specified size | ||
x058 | Magnitude of offset exceeds 16 bit | ||
x059 | Operand 2 too big | ||
x060 | Operand 1 too small | ||
x061 | Line too long | Size of a line ( after concatenation) is restricted to 600. | |
x062 | Too many tokens in a line | The number of tokens in a line is restricted to 150. | |
x063 | |||
x064 | Operand is expected | ||
x065 | Constant expected | A constant (numeric) value is expected in the current context. Note that a label - more exactly: the offset part of a label's address - is not a constant value, since the final value is calculated by the linker ( or the OS loader ) only. | |
x066 | Constant operand is expected | The expression evaluator accepts a constant only in the current context. | |
x067 | .ELSE clause already occured in this .IF block | An .IF block may contain 0 or 1 .ELSE clauses and it must be the last clause before .ENDIF. | |
x068 | Multiple overrides | ||
x069 | Segment, group or segment register expected | The operand before the colon operator (:) must be a segment, group or segment register. | |
x070 | Identifier too long | Identifer names are restricted to 247. This is a hard limit for OMF output format. For other formats, the limit may be extended by adjusting and recompiling the source code. | |
x071 | Invalid operand size for instruction | ||
x072 | Not supported: <directive> | Message is displayed if one of the follwing options is specified: OPTION READONLY, OPTION EXPR16, OPTION OLDMACROS. Those are currently not supported. | |
x073 | Size not specified, assuming: <type> | this is a warning. <type> may be BYTE, WORD or DWORD. The message may occur if an
immediate value is written to an untyped memory reference:
mov [ebx], 1JWasm makes a guess and displays the warning, while Masm will display an error in such cases. |
|
x074 | Floating-point initializer ignored | ||
x075 | Only SHORT and NEAR jump distance is allowed | Conditional jump (Jcc) instruction destination cannot be far. | |
x076 | Initializer magnitude too large for specified size | ||
x077 | Segment attribute is defined already: <attribute> | ||
x078 | Segment definition changed: %s, %s | ||
x079 | Class name too long | Segment class names are restricted to 255 in size. | |
x080 | Block nesting error: %s | ||
x081 | Segment attribute is unknown: %s | ||
x082 | Must be in segment block | ||
x083 | Segment not defined: <segment> | ||
x084 | Colon is expected | ||
x085 | Invalid qualified type: %s | ||
x086 | Qualified type is expected | ||
x087 | |||
x088 | Library name is missing | ||
x089 | Cannot access label through segment registers: <label> | ||
x090 | Line too long after expansion: <line> | ||
x091 | Language type must be specified | ||
x092 | PROC, MACRO or macro loop directive must precede LOCAL | ||
x093 | Cannot nest procedures | ||
x094 | VARARG requires C calling convention | ||
x095 | Multiple .MODEL directives, .MODEL ignored | ||
x096 | Model is not declared | Without a model, simplified segment directives ( .CODE, .DATA, .CONST, .DATA?, .STACK, .FARDATA and .FARDATA? ) and directives .STARTUP, .EXIT cannot be used. | |
x097 | Backquote missing: `<identifier> | ||
x098 | COMMENT delimiter expected | ||
x099 | END directive required at end of file | ||
x100 | Nesting level too deep | ||
x101 | Macro nesting level too deep | ||
x102 | Symbol not defined : <symbol> | ||
x103 | |||
x104 | No filename specified. | ||
x105 | Out of Memory | This is a fatal error. With the 8086-version of jwasm, JWASMR, you'll see this error if you try to assemble something that contains a few thousand symbols. The 32- or 64-bit versions of jwasm should always have enough memory on modern machines. | |
x106 | Cannot open file: "<file>" [<error code>] | Error code ENOENT means "file not found". Other error codes are displayed as numbers | |
x107 | Cannot close file: <file> [<error code>] | ||
x108 | File write error: <file> [<error code>] | Usually happens if output media is read-only or full. | |
x109 | Invalid command-line option: <option> | ||
x110 | Internal error in <source file>(<line>) | This error shouldn't be seen in the release version. It's displayed if the internal assert() function is called, which usually is done when a "virtually impossible" error condition has occurred. | |
x111 | Expecting closing square bracket | ||
x112 | Expecting file name | ||
x113 | Too many errors | Use commandline option -e to set the max. number of errors that are displayed | |
x114 | forced error <message> | Generic "forced error" message | |
x115 | forced error: Value not equal to 0: <value> <text> | Error emitted by the .ERRNZ directive. | |
x116 | forced error: Value equal to 0: <value> <text> | Error emitted by the .ERRE directive. | |
x117 | forced error: symbol defined: <symbol> | Error emitted by the .ERRDEF directive. | |
x118 | forced error: symbol not defined: <symbol> | Error emitted by the .ERRNDEF directive. | |
x119 | forced error: string blank : <string> | Error emitted by the .ERRB directive. | |
x120 | forced error: string not blank : <string> | Error emitted by the .ERRNB directive. | |
x121 | forced error: strings not equal : <string> : <string> | Error emitted by the .ERRDIF and .ERRDIFI directives. | |
x122 | forced error: strings equal : <string> : <string> | Error emitted by the .ERRIDN and .ERRIDNI directives. | |
x123 | <file>(<line>): Included by | Additional error information if error occured in an include file. | |
x124 | <file>(<line>)[<macro>]: Macro called from | Additional error information if error occured inside a macro. | |
x125 | <file>(<line>): iteration <iteration>: Macro called from | Additional error information if error occured inside a loop macro (FOR, FORC, REPEAT, ...). | |
x126 | <file>(<line>): Main line code | Additional error information if error occured inside an include file or a macro. | |
x127 | Extending jump | ||
x128 | Directive ignored: %s | ||
x129 | number must be a power of 2 | ||
x130 | Incompatible with segment alignment: %s | ||
x131 | Segment expected: %s | ||
x132 | Incompatible CPU mode for 32-bit segment | ||
x133 | Far call is converted to near call. | ||
x134 | CPU option %s is not valid for selected CPU. | ||
x135 | Segment '%s' is in another group already | ||
x136 | Symbol type conflict: %s | ||
x137 | Conflicting parameter definition: %s | ||
x138 | PROC and PROTO calling convention conflict | ||
x139 | Non-benign %s redefinition: %s | ||
x140 | Too many bits in RECORD: %s | ||
x141 | Statement not allowed inside structure definition | ||
x142 | Unmatched block nesting: %s | ||
x143 | Symbol redefinition: %s | ||
x144 | Text item required | ||
x145 | INVOKE argument type mismatch: argument %u | ||
x146 | Too few arguments to INVOKE: %s | ||
x147 | VARARG parameter must be last | ||
x148 | LABEL parameter must be first | ||
x149 | Too many arguments in macro call: %s | ||
x150 | Missing operator in expression | ||
x151 | Unexpected literal found in expression: %s | Literals enclosed in <> or {} are items processed by the preprocessor or to initialize "structured" data items. If they're used otherwise, this error will occur. | |
x152 | Initializer must be a string or single item: %s | ||
x153 | Too many initial values for structure: %s | ||
x154 | Too many initial values for array: %s | ||
x155 | String or text literal too long | ||
x156 | PROLOGUE must be macro function | The user-defined prologue macro must be a macro function, that is, there must be an EXITM somewhere inside that returns a literal. | |
x157 | EPILOGUE must be macro procedure: %s | The user-defined epilogue macro must be a macro procedure, that is, there must NOT be an EXITM somewhere inside that returns a literal. | |
x158 | Reserved word expected | ||
x159 | INVOKE requires prototype for procedure | ||
x160 | Invalid type for data declaration: %s | ||
x161 | Operand must be RECORD type or field | ||
x162 | Unmatched macro nesting | ||
x163 | Empty (null) string | ||
x164 | No segment information to create fixup: %s | ||
x165 | Register value overwritten by INVOKE | ||
x166 | Missing quotation mark in string | ||
x167 | Divide by zero in expression | ||
x168 | General Failure | ||
x169 | Cannot have implicit far jump or call to near label | ||
x170 | Invalid use of register | ||
x171 | Distance invalid for current segment | ||
x172 | Initializer magnitude too large: %s | ||
x173 | Cannot add two relocatable labels | ||
x174 | Cannot define as public or external: <symbol_name> | ||
x175 | Positive value expected | ||
x176 | FAR not allowed in FLAT model COMM variables | ||
x177 | Too many arguments to INVOKE | ||
x178 | Directive must appear inside a macro | ||
x179 | Invalid type expression | ||
x180 | Cannot declare scoped code label as PUBLIC: <label> | ||
x181 | Invalid radix tag | ||
x182 | Instruction operand must have size | The instruction allows operands with more than just one size, and the wanted size cannot be guessed from the current operands. | |
x183 | Use of register assumed to ERROR | ||
x184 | Instructions and initialized data not supported in <seg_type> segments | <seg_type> may be BSS or AT. Such segments don't have data. | |
x185 | Literal expected after '=' | ||
x186 | No 4k Page-aligned segments in MS386 OMF | ||
x187 | GROUP directive invalid for COFF and ELF format | ||
x188 | Operand must be relocatable | ||
x189 | Constant or relocatable label expected | ||
x190 | [ELSE]IF2/.ERR2 not allowed, single-pass assembler | ||
x191 | Expression too complex for UNTILCXZ | ||
x192 | Operands must be in same segment | ||
x193 | Invalid use of external symbol: <symbol_name> | ||
x194 | For -coff leading underscore required for start label: <start_label> | ||
x195 | Invalid command-line value, default is used: %s | ||
x196 | Unknown fixup type: %u at <segment>.<offset> | ||
x197 | Unsupported fixup type for <format>: <type> | ||
x198 | Invalid fixup type for <format>: <type> at location <segment>.<offset> | ||
x199 | Syntax error in control-flow directive | ||
x200 | Invalid .model parameter for flat model | ||
x201 | Output format doesn't support externals: <symbol> | In formats BIN and MZ all references must be local to the module. | |
x202 | Invalid start label for -bin | ||
x203 | No start label defined | Warning, format MZ only: MZ-binaries usually have a start label. In some cases (i.e. overlays) a missing start label may be ok. | |
x204 | No stack defined | Warning, format MZ only: MZ-binaries usually have a stack. In some cases (i.e. overlays) a missing stack may be ok. | |
x205 | Invalid alignment - value must be 2^n (n=4..15) | ||
x206 | Index <num> is past end of string | The index argument of SUBSTR or INSTR is beyond the string argument length | |
x207 | Count value too large | ||
x208 | Count must be positive or zero | ||
x209 | Syntax error: <item> | The parser found an item that has no meaning in the current context | |
x210 | Directive ignored for COFF and ELF format: %s | Some directives ( usually segment-oriented ) make no sense in flat output formats | |
x211 | |||
x212 | Must use floating-point initializer | ||
x213 | ORG directive not allowed in unions | ||
x214 | Struct alignment must be 1, 2, 4, 8, 16 or 32 | ||
x215 | Structure cannot be instanced | ||
x216 | Missing angle bracket or brace in literal | ||
x217 | Nondigit in number: <number> | ||
x218 | 16bit fixup for 32bit label: %s | ||
x219 | Too many macro placeholders | The number of parameters and locals for a macro must not exceed 256 | |
x220 | Missing macro argument: %s, parameter %u | ||
x221 | Doesn't work with 32-bit segments: <directive> | Directives .STARTUP and .EXIT work for 16-bit only. | |
x222 | Segment exceeds 64k limit: %s | In MZ format, 16-bit segments are restricted to 64k. | |
x223 | Not supported with OMF format: %s | ||
x224 | Not supported with current output format: %s | ||
x225 | Unknown default prologue argument: %s | ||
x226 | LOADDS ignored in flat model | ||
x227 | Missing right parenthesis in expression | ||
x228 | Invalid operand for %s operator: %s | ||
x229 | Structure improperly initialized: %s | ||
x230 | Expected: %s | ||
x231 | Invalid data initializer | ||
x232 | Expected data label | Some operators ( LENGTH, SIZE ) work with data labels only. | |
x233 | Expression must be a code address | ||
x234 | -n Option needs a valid name parameter | ||
x235 | Constant value too large: <value> | the value of the constant doesn't fit in 64 or - if it is a number to be assigned to a symbolic constant - 32 bits. | |
x236 | Text macro was used before definition | this is a warning only. However, using text macros before they have been defined will force JWasm to do a full second pass, which increases assembly time. | |
x237 | Offset size incompatible with current segment | ||
x238 | Instruction form requires 80386 | ||
x239 | Group/Segment offset size conflict: <group offset> - <segment offset> | Segments within a group must all have the same offset size. | |
x240 | Assembly passes reached: <passes> | Although this is a warning only it usually indicates a severe problem. The assembler is very probably unable to calculate "final" values of all labels and has to be terminated by pressing Ctrl-C. | |
x241 | Filename parameter must be enclosed in <> or quotes | The INCBIN directive requires delimiters for its filename. | |
x242 | Start address on END directive ignored with .STARTUP | ||
x243 | Invalid symbol type in expression: <symbol> | The expression evaluator has encountered a symbol that is meaningless in expressions, for example a (text) macro. | |
x244 | Missing right parenthesis | ||
x245 | Directive must be in control block | ||
x246 | Expected: memory model | the .MODEL directive needs at least one parameter, the memory model. | |
x247 | Type is wrong size for register | ||
x248 | IF[n]DEF expects a plain symbol as argument | this is a warning. Masm accepts any expression as argument for directives [ELSE]IF[N]DEF, but the result probably isn't always what has been expected. | |
x249 | Jump destination must specify a label | ||
x250 | Ignored: <attribute> | An attribute or parameter of a directive was found, but not handled. See Known Bugs and missing Features for details about what features aren't implemented yet. | |
x251 | Missing argument for cmdline option | ||
x252 | Invalid coprocessor register | ||
x253 | Registers AH-DH may not be used with SPL-DIL or R8-R15 | 64-bit only. | |
x254 | .ENDPROLOG found before EH directives | 64-bit only. | |
x255 | Missing FRAME in PROC, no unwind code will be generated | 64-bit only. | |
x256 | Bad alignment for offset in unwind code | 64-bit only. | |
x257 | Nonzero value expected | ||
x258 | Size of prolog too big, must be < 256 bytes | 64-bit only. | |
x259 | Missing .ENDPROLOG: %s | 64-bit only. | |
x260 | .SAFESEH argument must be a PROC | ||
x261 | Directive ignored without -%s switch | ||
x262 | ELF GNU extensions (8/16-bit relocations) used | This is a warning only. The extensions are not "official", but the GNU linker LD will understand them. | |
x263 | Syntax error in expression | ||
x264 | Macro label not defined: %s | ||
x265 | Procedure argument or local not referenced: %s | This warning is displayed only if at least -W3 is specified. | |
x266 | Group definition too large, truncated: <group_name> | The size of the OMF record that is to define a group would exceed 4 kB. However, to see this error you'll have to define a group that is to comprise more than 1000 segments, | |
x267 | COMM variable exceeds 64K: <variable> | in 16-bit, the size of a COMM variable is restricted to 64 kB. | |
x268 | Must be public or external: %s | ||
x269 | parameter/local name is reserved word: %s | ||
x270 | real or BCD number not allowed | ||
x271 | structure field expected | ||
x272 | Constant value too large: <value> | the value of the constant doesn't fit in 64 or - if it is a number to be assigned to a symbolic constant - 32 bits. | |
x273 | ELSE clause already occured in this IF block | An IF block may contain 0 or 1 ELSE clauses and it must be the last clause before ENDIF. | |
x274 | Illegal use of segment register | ||
x275 | Group exceeds 64K: <group> | MZ format only: a group that contains 16-bit segments cannot be larger than 64 kB, because the group must fit into a physical segment. |