You have both nasm and masm tagged, which do you need? I am sure this can be done in NASM with some sort of macro, but in MASM it is a breeze.
ENOENT equ 2
EBADF equ 9
ENOMEM equ 12
EACCES equ 13
EINVAL equ 22
EMFILE equ 24
errentry struc
oscode dd ?
ernocode dd ?
errentry ends
.data
errtable errentry <ERROR_INVALID_FUNCTION, EINVAL>, \
<ERROR_FILE_NOT_FOUND, ENOENT>, \
<ERROR_PATH_NOT_FOUND, ENOENT>, \
<ERROR_TOO_MANY_OPEN_FILES, EMFILE>, \
<ERROR_ACCESS_DENIED, EACCES>, \
<ERROR_INVALID_HANDLE, EBADF>, \
<ERROR_ARENA_TRASHED, ENOMEM>, \
<ERROR_NOT_ENOUGH_MEMORY, ENOMEM>
; ...
.code
start:
NextCode:
cmp eax, errtable.oscode[ecx * 8]
jne NotFound
mov eax, errtable.ernocode[ecx * 8]
jmp Next
NotFound:
; Err number not found, return something
Next:
And some test code:
We will change the registers around so we don't need to save them around printf
include masm32rt.inc
ENOENT equ 2
EBADF equ 9
ENOMEM equ 12
EACCES equ 13
EINVAL equ 22
EMFILE equ 24
errentry struc
oscode dd ?
ernocode dd ?
errentry ends
.data
fmtint db "OS Code = %d, Err Code = %d", 13, 10, 0
fmtstr db "OS Code %d NOT FOUND!!!", 13, 10, 0
errtable errentry <ERROR_INVALID_FUNCTION, EINVAL>, \
<ERROR_FILE_NOT_FOUND, ENOENT>, \
<ERROR_PATH_NOT_FOUND, ENOENT>, \
<ERROR_TOO_MANY_OPEN_FILES, EMFILE>, \
<ERROR_ACCESS_DENIED, EACCES>, \
<ERROR_INVALID_HANDLE, EBADF>, \
<ERROR_ARENA_TRASHED, ENOMEM>, \
<ERROR_NOT_ENOUGH_MEMORY, ENOMEM>
; ...
errtable_len equ ($ - errtable) / 8
.code
start:
mov edi, 1
xor ebx, ebx
NextCode:
cmp edi, errtable.oscode[ebx * 8]
jne NotFound
invoke crt_printf, offset fmtint, errtable.oscode[ebx * 8], errtable.ernocode[ebx * 8]
jmp Next
NotFound:
; Err number not found, return something
invoke crt_printf, offset fmtstr, edi
Next:
inc ebx
inc edi
cmp edi, 12 ; loop 3 more than our test array
jne NextCode
inkey
invoke ExitProcess, 0
end start