Re: Which assembler (or compiler) to start with? (newbie question)



On Wed, 26 Dec 2007 07:34:16 -0800 (PST), s_dubrovich wrote:
http://www-cs-faculty.stanford.edu/~knuth/taocp.html
And the exercises can be done in whatever assembly language you want!
;;
Usage: Right mouse button toggles between black and white cells,
and adjusts the numbering. First set the black squares.
CAPS on: writes downward and TAB jumps vertical,
CAPS off: writes to the right, TAB jumps horizontal.
;;
[WINDOW_WIDTH 225 WINDOW_HEIGHT 225]
[IDC_ROWS 110 IDC_COLUMNS 210 IDC_OK 500]

[AppName: b$ "Cryptic Crossword.", 0]
[ClassName: b$ "SKELETON", 0]
[<32 flag: d$ 0]
[hWnd: d$ ? hBlackPen: d$ ? hFont: d$ ? hNumFont: d$ ?
hWhiteBrush: d$ ? hBlackBrush: d$ ?]
[<32 changetab:
@pad: b$ 0 #32
@space: b$ ' '
@pad1: b$ 0 #31
@chars: b$ 0 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 0 0 0 0 0 #2
@pad2: b$ 0 #64
@umlauts: b$ 0 0 0 0 'Ä' 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 'Ö' 0 0 0 0 0 'Ü' 0 0 0 #2]
[rows: d$ 9 columns: d$ 9]
[current_row: d$ 0 current_column: d$ 0]
[Horizontal_row: d$ 0 Horizontal_column: d$ 0
Vertical_row: d$ 0 Vertical_column: d$ 0]
[<32 column_buffer: b$ ' ' #(19*19)]
[<32 puzzle0: b$ 0 #(19*19)]
[<32 puzzle1: b$ 0 #(19*19)]
[<32 rcZells: d$ 0 0 0 0 #362]
[<32 numbuf: b$ 0 #16]

[<32 wcx: ; WNDCLASSEX
@cbSize: d$ len
@style: d$ &CS_HREDRAW+&CS_VREDRAW
@lpfnWndProc: d$ MainWindowProc @cbClsExtra: d$ 0
@cbWndExtra: d$ 0 @hInstance: d$ 0
@hIcon: d$ 0 @hCursor: d$ 0
@hbrBackground: d$ &COLOR_WINDOW+1 @lpszMenuName: d$ 0
@lpszClassName: d$ ClassName @hIconSm: d$ 0]

[psx: ; PAINTSTRUCT
@hdc: D$ 0 @fErase: D$ 0
@rcPaint.left: D$ 0 @rcPaint.top: D$ 0
@rcPaint.right: D$ 0 @rcPaint.bottom: D$ 0
@fRestore: D$ 0 @fIncUpdate: D$ 0
@rgbReserved: B$ 0 #32]

[rect: ; RECT
@left: d$ 0 @top: d$ 0
@right: d$ WINDOW_WIDTH @bottom: d$ WINDOW_HEIGHT]

[msg: ; MSG
@hwnd: D$ 0 @message: D$ 0 @wParam: D$ 0 @lParam: D$ 0
@time: D$ 0 @pt.x: D$ 0 @pt.y: D$ 0]

[<16 nlf: ; LOGFONT
@lfHeight: D$ 10 @lfWidth: D$ 6
@lfEscapement: D$ 0 @lfOrientation: D$ 0
@lfWeight: D$ &FW_NORMAL @lfItalic: B$ 0
@lfUnderline: B$ 0 @lfStrikeOut: B$ 0
@lfCharSet: B$ &ANSI_CHARSET
@lfOutPrecision: B$ &OUT_DEFAULT_PRECIS
@lfClipPrecision: B$ &CLIP_DEFAULT_PRECIS
@lfQuality: B$ &DEFAULT_QUALITY
@lfPitchAndFamily: B$ &DEFAULT_PITCH
@lfFaceName: B$ "Courier New", 0]

[<16 clf: ; LOGFONT
@lfHeight: D$ 8 @lfWidth: D$ 8
@lfEscapement: D$ 0 @lfOrientation: D$ 0
@lfWeight: D$ &FW_NORMAL @lfItalic: B$ 0
@lfUnderline: B$ 0 @lfStrikeOut: B$ 0
@lfCharSet: B$ &ANSI_CHARSET
@lfOutPrecision: B$ &OUT_DEFAULT_PRECIS
@lfClipPrecision: B$ &CLIP_DEFAULT_PRECIS
@lfQuality: B$ &DEFAULT_QUALITY
@lfPitchAndFamily: B$ &DEFAULT_PITCH
@lfFaceName: B$ "Fixedsys", 0]

[Dialog: D$ 090CE08C2 0 U$ 07 0 0 04C 030 0 '' 0 'Grid' 0
08 'Fixedsys' 0]
[Control0000: D$ 050812001 0 U$ 06 05 020 0A 064 0FFFF 081 '1' 0 0]
; No creation data
[Control0001: D$ 050000017 0 U$ 04 04 020 0A 06E 'msctls_updown32' 0
'New Control' 0 0]
[Control0002: D$ 050812001 0 U$ 028 05 020 0A 0C8 0FFFF 081 '1' 0 0]
; No creation data
[Control0003: D$ 050000017 0 U$ 030 06 020 0A 0D2 'msctls_updown32' 0
'New Control' 0 0]
[Control0004: D$ 050000000 0 U$ 06 012 020 0A 012C 0FFFF 082
'Rows' 0 0]
[Control0005: D$ 050000000 0 U$ 028 013 020 0A 012D 0FFFF 082
'Columns' 0 0]
[Control0006: D$ 050000001 0 U$ 05 01F 043 0A 01F4 0FFFF 080
'OK' 0 0]

Main: fninit
call 'comctl32.InitCommonControls'
xor ebx ebx
call 'user32.DialogBoxIndirectParamA' ebx Dialog ebx,
GridDialogProc ebx
cmp eax 1 | jc ExitProg
call 'kernel32.GetModuleHandleA' &NULL
cmp eax 1 | jc ExitProg | mov d$wcx@hInstance eax
call 'user32.LoadIconA' &NULL &IDI_APPLICATION
cmp eax 1 | jc ExitProg | mov d$wcx@hIcon eax
call 'user32.LoadCursorA' &NULL &IDC_ARROW
cmp eax 1 | jc ExitProg | mov d$wcx@hCursor eax
; Register the window class for the main window.
call 'user32.RegisterClassExA' wcx
cmp eax 1 | jc ExitProg
call 'user32.AdjustWindowRectEx' rect,
&WS_OVERLAPPED+&WS_CAPTION+&WS_SYSMENU+&WS_MINIMIZEBOX,
&NULL &NULL
cmp eax 1 | jc ExitProg
mov esi d$rect@right | sub esi d$rect@left
mov edi d$rect@bottom | sub edi d$rect@top
call 'user32.GetSystemMetrics' &SM_CXSCREEN
sub eax esi | shr eax 1 | mov ebx eax
call 'user32.GetSystemMetrics' &SM_CYSCREEN
sub eax edi | shr eax 1
; Create the main window.
call 'user32.CreateWindowExA' &NULL ClassName AppName,
&WS_OVERLAPPED+&WS_CAPTION+&WS_SYSMENU+&WS_MINIMIZEBOX,
ebx eax esi edi,
&NULL &NULL,
d$wcx@hInstance &NULL
cmp eax 1 | jc ExitProg | mov d$hWnd,eax
; Show the window and paint its contents.
call 'user32.ShowWindow' eax &SW_SHOWDEFAULT
call 'user32.UpdateWindow' d$hWnd
jmp F1>

; Start the message loop.
B1: call 'user32.TranslateMessage' msg
call 'user32.DispatchMessageA' msg
F1: call 'user32.GetMessageA' msg &NULL 0 0
test eax eax | jnz B1
; Return the exit code to Windows.
call 'kernel32.ExitProcess' d$msg@wParam

ExitProg: call 'kernel32.GetLastError'
call 'kernel32.ExitProcess' eax

align 16
proc MainWindowProc:
arguments @hWnd @uMsg @wParam @lParam
uses ebx esi edi

mov eax d@uMsg
P1: cmp eax &WM_CREATE | jne P1>>
call puzzle
push ebp | mov ebp rcZells
xor eax eax | xor ebx ebx ; left, top
mov ecx 25, edx 25 ; right, bottom
mov edi d$rows
B1: mov esi d$columns
B2: mov d$ebp eax, d$ebp+4 ebx, d$ebp+8 ecx, d$ebp+12 edx
add ebp 16 | add eax 25 | add ecx 25
dec esi | jnz B2
xor eax eax | mov ecx 25
add ebx 25 | add edx 25
dec edi | jnz B1
pop ebp

call 'gdi32.CreateFontIndirectA' clf
mov d$hFont eax
call 'gdi32.CreateFontIndirectA' nlf
mov d$hNumFont eax

call 'gdi32.GetStockObject' &BLACK_PEN
mov d$hBlackPen eax
call 'gdi32.GetStockObject' &WHITE_BRUSH
mov d$hWhiteBrush eax
call 'gdi32.GetStockObject' &BLACK_BRUSH
mov d$hBlackBrush eax
jmp E0>>

P1: cmp eax &WM_SETFOCUS | jne P1>
; Create a solid black caret.
call 'user32.CreateCaret' d@hWnd &NULL 25 25
; Adjust the caret position, in client coordinates.
imul esi d$current_column 25 | imul edi d$current_row 25
call 'user32.SetCaretPos' esi edi
; Display the caret.
call 'user32.ShowCaret' d@hWnd
jmp E0>>

P1: cmp eax &WM_CHAR | jne P1>>
call 'user32.GetKeyState' &VK_CAPITAL | mov d$flag eax
mov eax d@wParam, esi d$columns, edi d$rows
mov ecx d$current_column, edx d$current_row

cmp eax &VK_TAB | je T0>>
cmp eax &VK_BACK | je F1>>
mov al b$changetab+eax | test al al | jz E0>>
; Write the character to the buffer.
mov ebx edx | imul ebx esi | add ebx ecx
mov b$column_buffer+ebx al | push ebx
test d$flag 1 | jnz F5>>
; Increment cursor position.
B1: add ecx 1 | cmp ecx esi | jb F4>> | xor ecx ecx
add edx 1 | cmp edx edi | jb F4>> | xor edx edx
F4: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz B1 | pop ebx
jmp F3>>

; Increment cursor position.
F5: B1: add edx 1 | cmp edx edi | jb F4>> | xor edx edx
add ecx 1 | cmp ecx esi | jb F4>> | xor ecx ecx
F4: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz B1 | pop ebx
jmp F3>

; Decrement cursor position.
F1: test d$flag 1 | jnz F6>>
sub ecx 1 | jns F2> | lea ecx d$esi-1
sub edx 1 | jns F2> | lea edx d$edi-1
; Write a space character to the buffer.
F2: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz F1
mov b$column_buffer+ebx ' '
jmp F3>

; Decrement cursor position.
F6: sub edx 1 | jns F2> | lea edx d$edi-1
sub ecx 1 | jns F2> | lea ecx d$esi-1
; Write a space character to the buffer.
F2: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz F6
mov b$column_buffer+ebx ' '

; Set new row and column and initiate redraw.
F3: mov d$current_column ecx, d$current_row edx
shl ebx 4 | add ebx rcZells
call 'user32.InvalidateRect' d@hWnd ebx &TRUE
jmp E0>>

T0: test d$flag 1 | jnz T5>>
mov ecx d$Horizontal_column, edx d$Horizontal_row
T1: inc ecx | cmp ecx esi | jb T2> | xor ecx ecx
inc edx | cmp edx edi | jb T2> | xor edx edx
T2: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz T1
test ecx ecx | jz T3>
lea eax d$esi-1 | cmp ecx eax | je T1
test b$puzzle0+ebx-1 1 | jz T1
T3: test b$puzzle0+ebx+1 1 | jnz T1
mov d$Horizontal_column ecx, d$Horizontal_row edx
jmp F3<<

T5: mov ecx d$Vertical_column, edx d$Vertical_row
T1: inc ecx | cmp ecx esi | jb T2> | xor ecx ecx
inc edx | cmp edx edi | jb T2> | xor edx edx
T2: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz T1
T4: test edx edx | jz T3>
lea eax d$edi-1 | cmp edx eax | je T1
mov eax ebx | sub eax esi
test b$puzzle0+eax 1 | jz T1
T3: test b$puzzle0+ebx+esi 1 | jnz T1
mov d$Vertical_column ecx, d$Vertical_row edx
jmp F3<<

P1: cmp eax &WM_LBUTTONDOWN | jne P1>
movzx eax w@lParam | mul d${d$ 0a3d70a4}
mov esi edx
movzx eax w@lParam+2 | mul d${d$ 0a3d70a4}
mov edi edx | imul edx d$columns | add edx esi
test b$puzzle0+edx 1 | jnz E0>>
mov d$current_column esi, d$current_row edi
imul esi 25 | imul edi 25
call 'user32.SetCaretPos' esi edi
jmp E0>>

P1: cmp eax &WM_RBUTTONDOWN | jne P1>
movzx eax w@lParam | mul d${d$ 0a3d70a4}
mov ebx edx
movzx eax w@lParam+2 | mul d${d$ 0a3d70a4}
imul edx d$columns | add ebx edx
xor b$puzzle0+ebx 1
shl ebx 4 | add ebx rcZells
call 'user32.InvalidateRect' d@hWnd rect &TRUE
mov ecx d$rows | imul ecx d$columns
mov edi puzzle1 | xor al al | rep stosb
call puzzle
jmp E0>>

P1: cmp eax &WM_KEYDOWN | jne P1>>
mov eax d@wParam, esi d$columns, edi d$rows
mov ecx d$current_column, edx d$current_row

P2: cmp eax &VK_UP | jne P2>
; Decrement cursor row.
B1: sub edx 1 | jns F2> | lea edx d$edi-1
sub ecx 1 | jns F2> | lea ecx d$esi-1
F2: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz B1
jmp F1>>

P2: cmp eax &VK_DOWN | jne P2>
; Increment cursor row.
B1: add edx 1 | cmp edx edi | jb F4>> | xor edx edx
add ecx 1 | cmp ecx esi | jb F4>> | xor ecx ecx
F4: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz B1
jmp F1>

P2: cmp eax &VK_LEFT | jne P2>
; Decrement cursor column.
B1: sub ecx 1 | jns F2> | lea ecx d$esi-1
sub edx 1 | jns F2> | lea edx d$edi-1
F2: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz B1
jmp F1>

P2: cmp eax &VK_RIGHT | jne E0>>
; Increment cursor column.
B1: add ecx 1 | cmp ecx esi | jb F4>> | xor ecx ecx
add edx 1 | cmp edx edi | jb F4>> | xor edx edx
F4: mov ebx edx | imul ebx esi | add ebx ecx
test b$puzzle0+ebx 1 | jnz B1

F1: mov d$current_column ecx, d$current_row edx
imul ecx 25 | imul edx 25
call 'user32.SetCaretPos' ecx edx
jmp E0>>

P1: cmp eax &WM_PAINT | jne P7>>
call 'user32.BeginPaint' d@hWnd psx
call 'user32.HideCaret' d@hWnd
call 'gdi32.GetStockObject' &BLACK_PEN
call 'gdi32.SelectObject' d$psx@hdc eax
call 'gdi32.SelectObject' d$psx@hdc d$hNumFont
call 'gdi32.SetBkMode' d$psx@hdc &TRANSPARENT
; Draw the grid.
xor ebx ebx
mov edi d$rows
B1: mov esi d$columns
B2: test b$puzzle0+ebx 1
mov eax d$hBlackBrush | cmovz eax d$hWhiteBrush
call 'gdi32.SelectObject' d$psx@hdc eax
lea eax d$rcZells+ebx*8 | lea eax d$eax+ebx*8
call 'gdi32.Rectangle' d$psx@hdc d$eax d$eax+4,
d$eax+8 d$eax+12
inc ebx | dec esi | jnz B2
dec edi | jnz B1<<

xor ebx ebx
mov edi d$rows
B1: mov esi d$columns
B2: movzx eax b$puzzle1+ebx | test eax eax | jz F1>>
mov d$numbuf 0 | xor ecx ecx
L1: push eax | mul d${d$ 01999999a}
mov eax edx | imul edx 10 | sub d$esp edx | pop edx
shl ecx 8 | lea ecx d$ecx+edx+030 | inc d$numbuf
test eax eax | jnz L1 | mov d$numbuf+4 ecx
F3: lea ecx d$rcZells+ebx*8 | lea ecx d$ecx+ebx*8
mov edx d$ecx+12, ecx d$ecx+8
sub ecx 23 | sub edx 23
call 'gdi32.TextOutA' d$psx@hdc ecx edx numbuf+4,
d$numbuf
F1: inc ebx | dec esi | jnz B2<<
dec edi | jnz B1<<

call 'gdi32.SelectObject' d$psx@hdc d$hFont
xor ebx ebx, edi edi
B1: xor esi esi
B2: imul edx edi 25 | add edx 6
imul ecx esi 25 | add ecx 6
lea eax d$ColumnBuffer+ebx
call 'gdi32.TextOutA' d$psx@hdc ecx edx eax 1
add ebx 1
add esi 1 | cmp esi d$columns | jb B2 | xor esi esi
add edi 1 | cmp edi d$rows | jb B1
imul edi d$current_column 25 | imul esi d$current_row 25
call 'user32.SetCaretPos' edi esi
call 'user32.ShowCaret' d@hWnd
call 'user32.EndPaint' d@hWnd psx
jmp E0>

P7: cmp eax &WM_DESTROY | jne P8>
E9: call 'gdi32.DeleteObject' d$hFont
call 'user32.PostQuitMessage' &NULL

P8: call 'user32.DefWindowProcA' d@hWnd d@uMsg,
d@wParam d@lParam
jmp P9>

E1: mov eax &TRUE | jmp P9>
E0: xor eax eax
endp

align 16
proc GridDialogProc: ; Tag Dialog 10
arguments @hwndDlg @uMsg @wParam @lParam
uses ebx esi edi

mov eax d@uMsg
P1: cmp eax &WM_INITDIALOG | jne P1>
call 'user32.SendDlgItemMessageA' d@hwndDlg IDC_ROWS,
&UDM_SETRANGE, 0, (5*65536)+19
call 'user32.SendDlgItemMessageA' d@hwndDlg IDC_ROWS,
&UDM_SETPOS, 0, 9
call 'user32.SendDlgItemMessageA' d@hwndDlg,
IDC_COLUMNS &UDM_SETRANGE 0 (5*65536)+19
call 'user32.SendDlgItemMessageA' d@hwndDlg,
IDC_COLUMNS &UDM_SETPOS 0 9
jmp E1>>

P1: cmp eax &WM_COMMAND | jne P8>>
mov eax d@wParam, edx eax | shr edx 16
cmp dx &BN_CLICKED | jne E0>>

L6: cmp ax IDC_OK | jne E0>>
call 'user32.SendDlgItemMessageA' d@hwndDlg IDC_ROWS,
&UDM_GETPOS 0 0
mov d$rows eax | imul eax 25 | mov d$rect@bottom eax
call 'user32.SendDlgItemMessageA' d@hwndDlg,
IDC_COLUMNS &UDM_GETPOS 0 0
mov d$columns eax | imul eax 25 | mov d$rect@right eax
jmp L1>

P8: cmp eax &WM_CLOSE | jne E0> | xor eax eax
L1: call 'user32.EndDialog', d@hwndDlg, eax
jmp P9>

E0: xor eax eax | jmp P9>
E1: mov eax &TRUE
EndP

align 16
subrt puzzle:
mov edx 1 ; Current number.
xor ecx ecx
on: xor ebx ebx
nxt: test b$puzzle0+ecx+ebx 255 ; White square?
jz upper_column
mov eax d$columns | sub eax 1
cmp ebx eax | je no_number
inc ebx
jmp nxt
upper_column:
test ecx ecx ; First row?
jz no_upper
lea eax d$puzzle0+ecx+ebx | sub eax d$columns
test b$eax 255 ; Square above black?
jz test_left
no_upper: mov eax d$rows | sub eax 1 | imul eax d$columns
cmp ecx eax ; Last row?
je test_left
lea eax d$puzzle0+ecx+ebx | add eax d$columns
test b$eax 255 ; Square below white?
jz number
test_left:test ebx ebx ; First column?
jz test_right
test b$puzzle0-1+ecx+ebx 255 ; Square to the left black?
jz no_number
mov eax d$columns | sub eax 1
cmp ebx eax ; Last column?
je no_number
test_right:
test b$puzzle0+1+ecx+ebx 255 ; Square to the right white?
jnz no_number
number: mov b$puzzle1+ecx+ebx dl
inc edx
no_number:mov eax d$columns | sub eax 1
cmp ebx eax
je no_coladd
inc ebx ; Increment column.
jmp nxt
no_coladd:mov eax d$rows | sub eax 1 | imul eax d$columns
cmp ecx eax
je off
add ecx d$columns
inc edi
jmp on
off: ret
ends puzzle

;------------------------
; General purpose macros:
;------------------------
[push | push #1 | #+1] [pop | pop #1 | #+1] [mov | mov #1 #2 | #+2]
[inc | inc #1 | #+1] [dec | dec #1 | #+1] [xor | xor #1 #2 | #+2]
[movq | movq #1 #2 | #+2]
[call | push #L>2 | call #1] [subrt | #1] [ends | nope]
[Proc | &1=0 | &2=0 | &3= | #1 | push ebp | mov ebp esp]
[Arguments | {#1 Arg#x} | #+1 | &1=SizeOf#x]
[Argument | {#1 Arg#x} | #+1 | &1=SizeOf#x]
[Local | {#1 Local#x} | #+1 | sub esp SizeOf#x | &2=SizeOf#x]
[StrucPtrs | {#3 ebp+#2+#F} | #+2]
[Structure | {#1 ebp-&2-4} | sub esp #2+4 | mov D$#1 esp
| StrucPtrs 0-&2-#2-4 #L>3]
[Uses | push #1>L | &3=pop #L>1]
[EndP | P9: | &3 | mov esp ebp | pop ebp | ret &1]
[Arg1 ebp+8 Arg2 ebp+12 Arg3 ebp+16 Arg4 ebp+20 Arg5 ebp+24
Arg6 ebp+28 Arg7 ebp+32 Arg8 ebp+36 Arg9 ebp+40 Arg10 ebp+44]
[Local1 ebp-4 Local2 ebp-8 Local3 ebp-12 Local4 ebp-16
Local5 ebp-20 Local6 ebp-24 Local7 ebp-28 Local8 ebp-32
Local9 ebp-36 Local10 ebp-40]
[SizeOf1 4 SizeOf2 8 SizeOf3 12 SizeOf4 16 SizeOf5 20
SizeOf6 24 SizeOf7 28 SizeOf8 32 SizeOf9 36 SizeOf10 40]
--
wfz
.


Quantcast