NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: HD1920.1 on May 17, 2014, 04:50:59 PM
-
Why is there no window?
struc WNDCLASS
.style: resd 1
.lpfnWndProc: resq 1
.cbClsExtra: resd 1
.cbWndExtra: resd 1
.hInstance: resq 1
.hIcon: resq 1
.hCursor: resq 1
.hbrBackground: resq 1
.lpszMenuName: resq 1
.lpszClassName: resq 1
endstruc
struc MSG
.hWnd: resq 1
.message: resd 1
.wParam: resq 1
.lParam. resq 1
.time: resd 1
.ptx: resd 1
.pty: resd 1
endstruc
extern LoadIconA
extern LoadCursorA
extern RegisterClassA
extern CreateWindowExA
extern ShowWindow
extern UpdateWindow
extern GetMessageA
extern TranslateMessage
extern DispatchMessageA
extern DefWindowProcA
extern MessageBoxA
extern PostQuitMessage
section .data
wc: istruc WNDCLASS
iend
Msg: istruc MSG
iend
MyWndClass db "MyWindowClass", 0
WndTitle db "window", 0
EndMessage db "OH, PLEASE NOT!", 0
section .text
global Start
Start:
sub rsp, 0x68
mov [rsp+0x70], rcx
mov [rsp+0x78], rdx
mov [rsp+0x80], r8
mov [rsp+0x88], r9d
mov dword [wc + WNDCLASS.style], 3
mov qword [wc + WNDCLASS.lpfnWndProc], WndProc
xor rax, rax
mov dword [wc + WNDCLASS.cbClsExtra], eax
mov dword [wc + WNDCLASS.cbWndExtra], eax
mov rax, [rsp+0x70]
mov qword [wc + WNDCLASS.hInstance], rax
xor rcx, rcx
mov rdx, 32512
call LoadIconA
mov qword [wc + WNDCLASS.hIcon], rax
xor rcx, rcx
mov rdx, 32512
call LoadCursorA
mov qword [wc + WNDCLASS.hCursor], rax
mov qword [wc + WNDCLASS.hbrBackground], 6
xor rax, rax
mov qword [wc + WNDCLASS.lpszMenuName], rax
mov qword [wc + WNDCLASS.lpszClassName], MyWndClass
mov rcx, wc
call RegisterClassA
xor rcx, rcx
mov rdx, MyWndClass
mov r8, WndTitle
mov r9d, 0x00CF0000
mov dword [rsp+0x20], 300
mov dword [rsp+0x28], 200
mov dword [rsp+0x30], 300
mov dword [rsp+0x38], 200
xor rax, rax
mov qword [rsp+0x40], rax
mov qword [rsp+0x48], rax
mov rax, qword [rsp+0x70]
mov qword [rsp+0x50], rax
xor rax, rax
mov qword [rsp+0x58], rax
call CreateWindowExA
mov qword [rsp+0x68], rax
mov rcx, rax
mov edx, dword [rsp+0x88]
call ShowWindow
mov rcx, qword [rsp+0x68]
call UpdateWindow
jmp MessageLoop
HandleMessage:
mov rcx, Msg
call TranslateMessage
mov rcx, Msg
call DispatchMessageA
MessageLoop:
mov rcx, Msg
xor rdx, rdx
xor r8, r8
xor r9, r9
call GetMessageA
test rax, rax
jnz HandleMessage
xor rax, rax
add rsp, 0x68
ret
WndProc:
sub rsp, 0x68
mov qword [rsp+0x70], rcx
mov dword [rsp+0x78], edx
mov qword [rsp+0x80], r8
mov qword [rsp+0x88], r9
cmp edx, 2
je quit
jmp not_interesting
quit:
xor rcx, rcx
mov rdx, EndMessage
mov r8, MyWndClass
mov r9, 0x30
call MessageBoxA
xor rcx, rcx
call PostQuitMessage
xor rax, rax
add rsp, 0x68
ret
not_interesting:
mov rcx, qword [rsp+0x70]
mov edx, dword [rsp+0x78]
mov r8, qword [rsp+0x80]
mov r9, qword [rsp+0x88]
call DefWindowProcA
add rsp, 0x68
ret
-
Structures are not correctly aligned.
-
I sent that code to Encryptor256 Investigation Department, and got a result.
Structures are not correctly aligned.
Yes!
This works, fixed!
"HD1920.1.asm":
WNDCLASS.style equ (0) ; CHANGED
WNDCLASS.lpfnWndProc equ (8) ; CHANGED
WNDCLASS.cbClsExtra equ (16) ; CHANGED
WNDCLASS.cbWndExtra equ (20) ; CHANGED
WNDCLASS.hInstance equ (24) ; CHANGED
WNDCLASS.hIcon equ (32) ; CHANGED
WNDCLASS.hCursor equ (40) ; CHANGED
WNDCLASS.hbrBackground equ (48) ; CHANGED
WNDCLASS.lpszMenuName equ (56) ; CHANGED
WNDCLASS.lpszClassName equ (64) ; CHANGED
WNDCLASS_SIZE equ (72) ; CHANGED
MSG.hwnd equ (0) ; CHANGED
MSG.message equ (8) ; CHANGED
MSG.wParam equ (16) ; CHANGED
MSG.lParam equ (24) ; CHANGED
MSG.time equ (32) ; CHANGED
MSG.pt.x equ (36) ; CHANGED
MSG.pt.y equ (40) ; CHANGED
MSG_SIZE equ (48) ; CHANGED
extern LoadIconA
extern LoadCursorA
extern RegisterClassA
extern CreateWindowExA
extern ShowWindow
extern UpdateWindow
extern GetMessageA
extern TranslateMessage
extern DispatchMessageA
extern DefWindowProcA
extern MessageBoxA
extern PostQuitMessage
section .data
;wc: istruc WNDCLASS ; CHANGED
;iend ; CHANGED
;Msg: istruc MSG ; CHANGED
;iend ; CHANGED
wc: times WNDCLASS_SIZE db 0 ; CHANGED
Msg: times MSG_SIZE db 0 ; CHANGED
MyWndClass db "MyWindowClass", 0
WndTitle db "window", 0
EndMessage db "OH, PLEASE NOT!", 0
section .text
;global Start ; CHANGED
;Start: ; CHANGED
global main ; CHANGED
main: ; CHANGED
sub rsp, 0x68
mov [rsp+0x70], rcx
mov [rsp+0x78], rdx
mov [rsp+0x80], r8
mov [rsp+0x88], r9d
mov dword [wc + WNDCLASS.style], 3
mov qword [wc + WNDCLASS.lpfnWndProc], WndProc
xor rax, rax
mov dword [wc + WNDCLASS.cbClsExtra], eax
mov dword [wc + WNDCLASS.cbWndExtra], eax
mov rax, [rsp+0x70]
mov qword [wc + WNDCLASS.hInstance], rax
xor rcx, rcx
mov rdx, 32512
call LoadIconA
mov qword [wc + WNDCLASS.hIcon], rax
xor rcx, rcx
mov rdx, 32512
call LoadCursorA
mov qword [wc + WNDCLASS.hCursor], rax
mov qword [wc + WNDCLASS.hbrBackground], 6
xor rax, rax
mov qword [wc + WNDCLASS.lpszMenuName], rax
mov qword [wc + WNDCLASS.lpszClassName], MyWndClass
mov rcx, wc
call RegisterClassA
xor rcx, rcx
mov rdx, MyWndClass
mov r8, WndTitle
mov r9d, 0x00CF0000
mov dword [rsp+0x20], 300
mov dword [rsp+0x28], 200
mov dword [rsp+0x30], 300
mov dword [rsp+0x38], 200
xor rax, rax
mov qword [rsp+0x40], rax
mov qword [rsp+0x48], rax
mov rax, qword [rsp+0x70]
mov qword [rsp+0x50], rax
xor rax, rax
mov qword [rsp+0x58], rax
call CreateWindowExA
mov qword [rsp+0x68], rax
mov rcx, rax
mov rdx, 5 ; CHANGED
call ShowWindow
mov rcx, qword [rsp+0x68]
call UpdateWindow
jmp MessageLoop
HandleMessage:
mov rcx, Msg
call TranslateMessage
mov rcx, Msg
call DispatchMessageA
MessageLoop:
mov rcx, Msg
xor rdx, rdx
xor r8, r8
xor r9, r9
call GetMessageA
test rax, rax
jnz HandleMessage
xor rax, rax
add rsp, 0x68
ret
WndProc:
sub rsp, 0x68
mov qword [rsp+0x70], rcx
mov dword [rsp+0x78], edx
mov qword [rsp+0x80], r8
mov qword [rsp+0x88], r9
cmp edx, 2
je quit
jmp not_interesting
quit:
xor rcx, rcx
mov rdx, EndMessage
mov r8, MyWndClass
mov r9, 0x30
call MessageBoxA
xor rcx, rcx
call PostQuitMessage
xor rax, rax
add rsp, 0x68
ret
not_interesting:
mov rcx, qword [rsp+0x70]
mov edx, dword [rsp+0x78]
mov r8, qword [rsp+0x80]
mov r9, qword [rsp+0x88]
call DefWindowProcA
add rsp, 0x68
ret
I used gcc, because didn't wanted to search for a golink command line.
Compile: "nasm.exe -f win64 HD1920.1.asm -o HD1920.1.obj".
Build: "gcc HD1920.1.obj -o HD1920.1.exe".
Thanks for the challenge, it was fun to do, even if it will not run on you calculator, but
what's more important that it worked on mine pc.
Bye.
-
Great! ...but I wonder why? Problem with the "struc" macro? I haven't assembled either, but they "should" come out about the same, no? I can't help thinking that the "real" problem might be the "golink" command line. Did we have "subsys gui" in there someplace? (I don't know the correct syntax)
Best,
Frank
-
Great! ...but I wonder why? Problem with the "struc" macro? I haven't assembled either, but they "should" come out about the same, no?
Hi!
Structure macro is structure macro - it fulfills it's duty, the problem is that - if we want to program in windows environment or to replicate other higher level layer into assembly, then we have to follow the rules. For example the rule is "structure alignment", we have to follow this rule to make it work. Here is more information: x64 Software Conventions / Types and Storage / Structure Alignment Examples (http://msdn.microsoft.com/en-us/library/71kf49f1.aspx)
Structure macro is structure macro - it fulfills it's duty
This code:
bits 64
struc MSG
.hWnd: resq 1
.message: resd 1
.wParam: resq 1
.lParam. resq 1
.time: resd 1
.ptx: resd 1
.pty: resd 1
endstruc
%assign x MSG.hWnd
%warning MSG.hWnd x
%assign x MSG.message
%warning MSG.message x
%assign x MSG.wParam
%warning MSG.wParam x
Compiled with: "nasm.exe -f win64 ttt.asm -o ttt.obj".
Produces (I'm printing offsets here):
ttt.asm:14: warning: MSG.hWnd 0
ttt.asm:17: warning: MSG.message 8
ttt.asm:20: warning: MSG.wParam 12
Result is fine, but it is not aligned.
That macro generates invalid MSG structure, because MSG structure on windows is aligned on some byte boundaries.
That is - macro generates valid structure, but on windows it is invalid, because there is a need for alignment.
Should be like this:
hWnd is sizeof 8 and at offset 0.
message is sizeof 4 and at offset 8.
wParam is sizeof 8 at offset 16.
So, after message is inserted 4x padding bytes!
If you access 8x byte location, like wParam, then it has to be aligned on 8x byte boundaries.
So, and again, NASMX has solved all of these kind'a issues.
Use NASMX or Create your own macro or do it manually - define offsets.
Generally - Structure alignment is HLA crap, that we have to drag along us / work around / respect. :D
Bye.
-
Ah! Okay, I see the difference now. Thank you!
Best,
Frank
-
So, and again, NASMX has solved all of these kind'a issues.
Use NASMX or Create your own macro or do it manually - define offsets.
NASMX struc macros indeed solves these kinds of problems. Alignment issues are handled automagically according to the operating system specification. Thus they work with BSD, Linux, and Windows. Even better, using the same macro definition it will successfully port from 32-bit to 64-bit providing you use the correct member definitions ( such as ptrdiff_t or size_t ) without the developer having to even think about it. ;)
-
I used gcc, because didn't wanted to search for a golink command line.
Compile: "nasm.exe -f win64 HD1920.1.asm -o HD1920.1.obj".
Build: "gcc HD1920.1.obj -o HD1920.1.exe".
Oh, just "re-replace" the "global main" and "main:" with "global Start" and "Start:", assemble with "nasm -fwin64 HD1920.1.asm -o HD1920_1.obj" and link with "GoLink HD1920_1.obj user32.dll" (GoLink seems not to support dots in filenames).