flat assembler
Message board for the users of flat assembler.
Index
> Non-x86 architectures > WinCE & ARM questions Goto page 1, 2 Next |
Author |
|
ProMiNick 15 May 2018, 13:07
revolution, can you explain this trickery:
Code: if $+8-_#function<4096 ldr pc,[pc,_#function-$-8] else ldr r12,[pc] ldr pc,[r12] dw _#function end if Am I right?: pc point not to instruction start like (e|r)ip in x86, but to second one instruction after next instruction. why second part not so: Code: ldr pc,[pc] nop dw _#function And how you got coredll.inc it documented somewhere or you test this dll in wince, or extract it from *.BIN image? Quote: I drop this in first post if someone interests in emulator of arm & images for that emulator, & there are set of small programs for reverse engenering play too _________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. Last edited by ProMiNick on 18 May 2018, 19:15; edited 1 time in total |
|||
15 May 2018, 13:07 |
|
ProMiNick 16 May 2018, 10:12
one more...
Why apscall macros targeted for programs where programmer mix everithing within 1 PE section (sections are 4096 bytes aligned, and in many places maked macro branches that expects values distant from pc less than 4096 bytes)? examples: that simplification works only if we mix code & import within one section Code: if defined _#function & _#function-$-8<4096 & _#function-$-8>-4096 mov lr,pc ldr pc,[pc,_#function-$-8] else bl function end if Code: bl function or maybe it is ARM philosophy to mix everithig(code,data) relative in 4096 range, and than next portion. lea is not ARM instruction it is macro? it hardcoded in IDE? or it defined anywhere? |
|||
16 May 2018, 10:12 |
|
revolution 16 May 2018, 10:34
ProMiNick wrote: Why apscall macros targeted for programs where programmer mix everithing within 1 PE section (sections are 4096 bytes aligned, and in many places maked macro branches that expects values distant from pc less than 4096 bytes)? "function"s with a leading underscore (_) are external to the code so they need a linking call "ldr pc, ..." and the pointer is placed into the literal pool by the macros. A local function without the underscore can be called with a simple "bl ...". The 4096 constant is not the alignment, it is the restriction in the instruction encoding for LDR. ProMiNick wrote: lea is not ARM instruction it is macro? it hardcoded in IDE? or it defined anywhere? |
|||
16 May 2018, 10:34 |
|
ProMiNick 16 May 2018, 13:56
how to do this:
Code: section '.text' code readable executable apscall RegisterClass,wc section '.nomatter' data readable executable ; ensure that between "apscall RegisterClass,wc" & wc definition will be more than 4096 bytes section '.data' data readable executable wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class there 2 variants: use MOVEX instead of mov in PROCAPS.INC Code: if temp <> lastvalue MOV lr,value end if lastvalue=temp str lr,[sp,-tempcount*4-4] Code: else if ~ r\#p eq value MOV r\#p,value end if \\} with smthing like Code: macro MOVEXT dest,src { local ..started ..started: if src and 0ff000000h mov dest,src and 0ff000000h ; shifts are resolved? end if if src and 0ff0000h if $-..started orr dest,dest,src and 0ff0000h else mov dest,src and 0ff0000h end if end if if src and 0ff00h if $-..started orr dest,dest,src and 0ff00h else mov dest,src and 0ff00h end if end if if src and 0ffh if $-..started orr dest,dest,src and 0ffh else mov dest,src and 0ffh end if end if or add in block Code: reverse local ..arg found equ no match i[like]za,:parameter: \{ found equ \} match =no:*ustring,found:parameter \{ def_ustring ..arg,ustring,0 found equ \} ;add here match =no:some=,more,found:parameter \{ def_astring ..arg,parameter,0 found equ \} match =no,found \{ if parameter eqtype '' def_astring ..arg,parameter,0 end if \} tempcount=tempcount+1 add this Code: match =no:=far data,found:parameter \{ def_fardata ..arg,parameter found equ \} and Code: macro def_fardata labl,data {common align 4 ; is alignment needed? labl dw data} so after all code (syntax) is worked Code: section '.text' code readable executable apscall RegisterClass,far wc section '.data' data readable executable wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class previous one ever without needance in word far Code: match =no,found \{ if parameter eqtype '' def_astring ..arg,parameter,0 end if if parameter shr 12 = $ shr 12 ; same section same page - referencing throw pc else if parameter-$>200h | parameter-$<-200h ; if function located in 2 neibour pages - 512 bytes for function would be enough for referencing throw pc def_fardata ..arg,parameter else if \} but Code: apscall CreateWindowEx,0,_class,_title,$10000000,0,0,100,100,NULL,NULL,[wc.hInstance],NULL section '.data' data readable executable wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class full code what I test is Code: format PE GUI entry start include 'WINCE.INC' struct POINT x dw ? y dw ? ends struct WNDCLASS style dw ? lpfnWndProc dw ? cbClsExtra dw ? cbWndExtra dw ? hInstance dw ? hIcon dw ? hCursor dw ? hbrBackground dw ? lpszMenuName dw ? lpszClassName dw ? ends struct MSG hwnd dw ? message dw ? wParam dw ? lParam dw ? time dw ? pt POINT ends NULL = 0 MB_ICONERROR=0 ; no matter for now MB_OK=0 ; no matter for now COLOR_BTNFACE=0 ; no matter for now WM_DESTROY=$66 section '.text' code readable executable start: mov r12,data.begin apscall GetModuleHandleW,0 str r0, [r12,wc.hInstance-data.begin] ;ldr r12, [WindowProc] ;str r12, [wc.lpfnWndProc] ;mov r12, COLOR_BTNFACE+1 ;str r12, [wc.hbrBackground] ;ldr r12, [_class] ;str r12, [wc.lpszClassName] ;apscall LoadIconW,r0,IDI_APPLICATION;If I uncomment this ;str r0, [r12,wc.hIcon-data.begin]; and uncomment this - next one error disapiared in compilation, but it makes exe compiled errorneusly it crashed near the call to CreateWindowExW apscall RegisterClassW,far wc cmp r0,0 beq error apscall CreateWindowExW,0,_class,_title,$10000000,0,0,100,100,NULL,NULL,[wc.hInstance],NULL ; here I have error cmp r0,0 beq error msg_loop: apscall GetMessageW,msg,NULL,0,0 ; {LDR R0, msg; MOV R1, NULL; MOV R2, #0; MOV R3, #0; BL GetMessage} cmp r0, 0 beq end_loop apscall TranslateMessage,msg ; {LDR R0, msg; BL TranslateMessage} apscall DispatchMessageW,msg ; {LDR R0, msg; BL DispatchMessage} b msg_loop error: apscall MessageBoxW,NULL,_error,NULL,MB_ICONERROR+MB_OK ; MOV R0, NULL; LDR R1, _error; MOV R2, NULL; MOV R3, MB_ICONERROR+MB_OK; BL MessageBox} end_loop: apscall ExitThread,0 proc WindowProc nospil ,hwnd,wmsg,wparam,lparam cmp r1,WM_DESTROY beq .wmdestroy .defwndproc: apscall DefWindowProcW,R0,R1,R2,R3 B .finish .wmdestroy: apscall PostQuitMessage,0 mov r0,0 .finish: ret endp section '.data' data readable executable data.begin: _class du 'FASMWINCE',0 _title du 'WinCE program template',0 _error du 'Startup failed.',0 wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class msg MSG section '.idata' import data readable writeable library coredll,'COREDLL.DLL' include 'APICE\COREDLL.INC' |
|||
16 May 2018, 13:56 |
|
revolution 16 May 2018, 14:08
IF you need the address of WindowProc then try with ADR, instead of LDR.
Also, you can't address wc directly. You will need to load the address into a register first (maybe with ADR also), then you can use "str r12,[r0,WNDCLASS.lpfnWndProc]", assuming r0 is the address of wc. |
|||
16 May 2018, 14:08 |
|
ProMiNick 16 May 2018, 14:48
patched PROCAPS.INC:
Code: macro def_ustring labl,[string] {common labl dU string} macro def_astring labl,[string] {common labl dB string} Code: macro def_fardata labl,data {common align 4 ; is alignment needed? labl dw data} Code: macro apscall function,[parameter] { common local pcount,tempcount,found,.skip,.size,param,last_value,temp,size,instr,i_s,msize virtual nop temp=$-$$ end virtual if temp<>4 halt ;APSCALL macro NOT usable in thumb mode end if if ~ parameter eq if .size b .skip end if temp=$ tempcount=0 reverse local ..arg found equ no match i[like]za,:parameter: \{ Code: if like eqtype 0 if like shr 12 = $ shr 12 ; same section same page else if like-$>200h | like-$<-200h def_fardata ..arg,like end if end if Code: found equ \} match =no:*ustring,found:parameter \{ def_ustring ..arg,ustring,0 found equ \} match =no:some=,more,found:parameter \{ def_astring ..arg,parameter,0 found equ \} match =no,found \{ if parameter eqtype '' def_astring ..arg,parameter,0 end if Code: if parameter eqtype 0 if parameter shr 12 = $ shr 12 ; same section same page else if parameter-$>200h | parameter-$<-200h def_fardata ..arg,parameter end if end if Code: \} tempcount=tempcount+1 common pcount=tempcount align 4 .size=$-temp if .size .skip: end if lastvalue=1 shl 63 tempcount=0 reverse if tempcount<(pcount-4) found equ no define param parameter match [address],parameter \{ Code: if defined ..arg ADD lr,pc,..arg-$-8 LDR lr,[lr] else Code: LDR lr,[address] Code: end if all rest remain untouched compiled successfuly, but
_________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. |
||||||||||
16 May 2018, 14:48 |
|
ProMiNick 17 May 2018, 23:48
I canceled from avoiding word far in PROCAPS.
word far precedes values that used from other PE sections and therefore needed in special handling. Code: format PE GUI entry start include 'WINCE.INC' struct POINT x dw ? y dw ? ends struct WNDCLASS style dw ? lpfnWndProc dw ? cbClsExtra dw ? cbWndExtra dw ? hInstance dw ? hIcon dw ? hCursor dw ? hbrBackground dw ? lpszMenuName dw ? lpszClassName dw ? ends struct MSG hwnd dw ? message dw ? wParam dw ? lParam dw ? time dw ? pt POINT ends NULL = 0 MB_ICONERROR=0 ; no matter for now MB_OK=0 ; no matter for now COLOR_BTNFACE=0 ; no matter for now WM_DESTROY=$66 section '.text' code readable executable start: mov r12,data.begin apscall GetModuleHandleW,0 str r0, [r12,wc.hInstance-data.begin] apscall RegisterClassW,far wc cmp r0,0 beq error ; on call CreateWindowExW emulated WinCE OS freezes, if change beq with b then showed message "Startup failed." and program normaly closed apscall CreateWindowExW,0,far _class,far _title,$10000000,0,0,100,100,NULL,NULL,[wc.hInstance],NULL ; here I have error cmp r0,0 beq error msg_loop: apscall GetMessageW,far msg,NULL,0,0 ; {LDR R0, msg; MOV R1, NULL; MOV R2, #0; MOV R3, #0; BL GetMessage} cmp r0, 0 beq end_loop apscall TranslateMessage,far msg ; {LDR R0, msg; BL TranslateMessage} apscall DispatchMessageW,far msg ; {LDR R0, msg; BL DispatchMessage} b msg_loop error: apscall MessageBoxW,NULL,far _error,NULL,MB_ICONERROR+MB_OK ; MOV R0, NULL; LDR R1, _error; MOV R2, NULL; MOV R3, MB_ICONERROR+MB_OK; BL MessageBox} end_loop: apscall ExitThread,0 proc WindowProc nospil ,hwnd,wmsg,wparam,lparam cmp r1,WM_DESTROY beq .wmdestroy .defwndproc: apscall DefWindowProcW,R0,R1,R2,R3 B .finish .wmdestroy: apscall PostQuitMessage,0 mov r0,0 .finish: ret endp section '.skip' data readable writeable dd 0 section '.data' data readable writeable ; accidentaly previously section has executable flag instead of writeable data.begin: _class du 'FASMWINCE',0 _title du 'WinCE program template',0 _error du 'Startup failed.',0 align 4 ; when wc was misaligned program was crashed in "str r0, [r12,wc.hInstance-data.begin]" wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class msg MSG section '.idata' import data readable writeable library coredll,'COREDLL.DLL' include 'APICE\COREDLL.INC' Any ideas what is wrong in CreateWindowExW or in WindowProc processing?
_________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. |
|||||||||||
17 May 2018, 23:48 |
|
revolution 18 May 2018, 06:56
Can you attach a full set of sources for the code you assembled?. I'll see what I can find.
|
|||
18 May 2018, 06:56 |
|
ProMiNick 18 May 2018, 10:17
program donor for ideas attached
7kb in size (in wince HLL wrapper around main is perfect - it has many lines of code that actualy does nothing!)
_________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. |
|||||||||||||||||||||
18 May 2018, 10:17 |
|
ProMiNick 23 May 2018, 10:39
I patched winmain(start) in donor file so it will have more suitable form for making macros over it
Code: start ; DATA XREF: HEADER:00010100o ; HEADER:00010104o ... X = -0x78 Y = -0x74 nWidth = -0x70 nHeight = -0x6C hWndParent = -0x68 hMenu = -0x64 hInstance = -0x60 lpParam = -0x5C Msg = -0x50 WndClass = -0x30 STMFD SP!, {R0,LR} SUB SP, SP, #0x70 STR R0, [SP,#0x78+WndClass.hInstance] LDR R6, =dword_131F0 STR R0, [R6] MOV R5, R0 ANDEQ R0, R0, R0 ;smthing as nop only placeholder code is shrinked after optimizing ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop ANDEQ R0, R0, R0 ;smthing as nop MOV R0, #0 ; int STR R0, [SP,#0x78+WndClass.cbClsExtra] STR R0, [SP,#0x78+WndClass.cbWndExtra] STR R0, [SP,#0x78+WndClass.hCursor] STR R0, [SP,#0x78+WndClass.lpszMenuName] BL GetStockObject STR R0, [SP,#0x78+WndClass.hbrBackground] LDR R1, =aIdi_icon1 ; "IDI_ICON1" MOV R0, #0 ; hInstance BL LoadIconW STR R0, [SP,#0x78+WndClass.hIcon] MOV R0, #1 STR R0, [SP,#0x78+WndClass] LDR R0, =sub_111A0 STR R0, [SP,#0x78+WndClass.lpfnWndProc] LDR R7, =aYusu ; "Yusu" STR R7, [SP,#0x78+WndClass.lpszClassName] ADD R0, SP, #0x78+WndClass ; lpWndClass BL RegisterClassW MOV R1, R0,LSL#16 MOVS R0, R1,LSR#16 ADDEQ SP, SP, #0x70 LDMEQFD SP!, {R0,PC} MOV R0, #0 ; nIndex BL GetSystemMetrics LDR R1, =dword_131E0 STR R0, [R1] STR R0, [SP,#0x78+nWidth] ; nWidth ;maybe for macro value should be saved in r6 that free for use here MOV R0, #1 ; nIndex BL GetSystemMetrics LDR R1, =dword_131E4 STR R0, [R1] STR R0, [SP,#0x78+nHeight] ; nHeight ;maybe for macro value should be saved in r8 that free for use here MOV R0, #0 ; dwExStyle ; this line would precede apscall macro STR R0, [SP,#0x78+lpParam] ; lpParam STR R5, [SP,#0x78+hInstance] ; hInstance STR R0, [SP,#0x78+hMenu] ; hMenu STR R0, [SP,#0x78+hWndParent] ; hWndParent STR R0, [SP,#0x78+Y] ; Y STR R0, [SP,#0x78+X] ; X MOV R3, #0x10000000 ; dwStyle LDR R2, =aSysneitfSearch ; "Sysneitf Search" MOV R1, R7 ; lpClassName BL CreateWindowExW ;r0,r7,far aSysneitfSearch,$10000000,r0,r0,r6,r8,r0,r0,r5,r0 MOVS R4, R0 MOVEQ R0, #0 ADDEQ SP, SP, #0x70 LDMEQFD SP!, {R0,PC} LDR R1, =aAccelerator1 ; "Accelerator1" MOV R0, R5 ; hInstance BL LoadAcceleratorsW MOV R8, R0 MOV R1, R9 ; nCmdShow MOV R0, R4 ; hwnd BL ShowWindow MOV R0, R4 ; hwnd BL UpdateWindow loc_1112C ; CODE XREF: start+15Cj ; start+170j MOV R3, #0 ; wMsgFilterMax MOV R2, #0 ; wMsgFilterMin MOV R1, #0 ; hWnd ADD R0, SP, #0x78+Msg ; lpMsg BL GetMessageW CMP R0, #0 BEQ loc_11174 ADD R2, SP, #0x78+Msg ; lpMsg MOV R1, R8 ; hAccTable MOV R0, R4 ; hWnd BL TranslateAcceleratorW CMP R0, #0 BNE loc_1112C ADD R0, SP, #0x78+Msg ; pMsg BL TranslateMessage ADD R0, SP, #0x78+Msg ; lpMsg BL DispatchMessageW B loc_1112C ; --------------------------------------------------------------------------- loc_11174 ; CODE XREF: start+144j LDR R0, [SP,#0x78+Msg.wParam] ADD SP, SP, #0x70 LDMFD SP!, {R0,PC} ; End of function start of course after patch exe still works normally once again trying to make app (not task) in WinCE: Code: format PE GUI entry start include 'WINCE.INC' struct POINT x dw ? y dw ? ends struct WNDCLASS style dw ? lpfnWndProc dw ? cbClsExtra dw ? cbWndExtra dw ? hInstance dw ? hIcon dw ? hCursor dw ? hbrBackground dw ? lpszMenuName dw ? lpszClassName dw ? ends struct MSG hwnd dw ? message dw ? wParam dw ? lParam dw ? time dw ? pt POINT ends section '.text' code readable executable start: virtual at sp x dw ? y dw ? nWidth dw ? nHeight dw ? hWndParent dw ? hMenu dw ? hInstance dw ? lpParam dw ? Msg MSG WndClass WNDCLASS end virtual stmfd sp!, {r0,lr} sub sp, sp, $70 str r0, [WndClass.hInstance] ;ldr r6, [pc+..off_11198-$-8] ;ldr r6, =dword_131F0 ;str r0, [r6] mov r5, r0 mov r0, 0 str r0, [WndClass.cbClsExtra] str r0, [WndClass.cbWndExtra] str r0, [WndClass.hCursor] str r0, [WndClass.lpszMenuName] ;apscall LoadIconW,0,[..off_1119C] str r0, [WndClass.hIcon] apscall GetStockObject,r0 str r0, [WndClass.hbrBackground] mov r0, #1 str r0, [WndClass] ldr r0, [pc+..off_11194-$-8] ;ldr r0, =sub_111A0 str r0, [WndClass.lpfnWndProc] ldr r7, [pc+..off_11190-$-8] ;ldr r7, =_class str r7, [WndClass.lpszClassName] apscall RegisterClassW, addr WndClass mov r1, r0,lsl 16 movs r0, r1,LSR 16 addeq sp, sp, $70 ldmeqfd sp!, {r0,pc} apscall GetSystemMetrics,0 ;ldr r1, [pc+..off_11188-$-8] ;ldr r1, =dword_131E0 ;str r0, [r1] mov r6, r0 ;str r0, [nWidth] apscall GetSystemMetrics,1 ;ldr r1, [pc+..off_11184-$-8] ;ldr r1, =dword_131E0 ;str r0, [r1] mov r8, r0 ;str r0, [nWidth] mov r0, 0 apscall CreateWindowExW,r0,r7,[..off_11180],$10000000,r0,r0,r6,r8,r0,r0,r5,r0 movs r4, r0 addeq sp, sp, $70 ldmeqfd sp!, {r0,pc} ;apscall LoadAcceleratorsW,r5,[..off_1118C] ;mov r8, r0 apscall MessageBoxW,0,addr Text,addr Caption,0+0 apscall ExitThread,0 mov r8, r0 apscall ShowWindow,r4,r9 apscall UpdateWindow,r4 msg_loop: apscall GetMessageW,addr Msg,0,0,0 cmp r0, 0 beq end_loop ;apscall TranslateAcceleratorW,r4,r8,0,0 ;cmp r0, 0 ;bne msg_loop apscall TranslateMessage,addr Msg apscall DispatchMessageW,addr Msg b msg_loop end_loop: ldr r0, [Msg.wParam] add sp, sp, $70 ldmfd sp!, {r0,pc} ..off_11180 dw _title ;..off_11184 dw dword_131E4 ;..off_11188 dw dword_131E0 ..off_1118C dw aAccelerator1 ..off_11190 dw _class ..off_11194 dw WndProc ;WndProc ;..off_11198 dw dword_131F0 ..off_1119C dw aIdi_icon1 WndProc: stmfd sp!, {r4-r8,r11,lr} mov r5,r0 mov r7,r2 mov r8,r3 cmp r1,2 beq .wmdestroy apscall DefWindowProcW,r0,r1,r2,r3 ldmfd sp!, {r4-r8,r11,PC} .wmdestroy: apscall PostQuitMessage,0 mov r0,0 ldmfd sp!, {r4-r8,r11,PC} section '.data' data readable writeable _class du 'Yusu',0 _title du 'WinCE example app',0 ;aIdi_icon1 du 'IDI_ICON1',0 ;aAccelerator1 du 'Accelerator1',0 ;dword_131E0 dw ? ;dword_131E4 dw ? ;dword_131F0 dw ? section '.idata' import readable writeable library coredll,'COREDLL.DLL' include 'APICE\COREDLL.INC'
_________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. |
|||||||||||
23 May 2018, 10:39 |
|
revolution 24 May 2018, 11:03
Just a first look at your code I see this problem:
Code: mov r12,data.begin apscall GetModuleHandleW,0 str r0, [r12,wc.hInstance-data.begin] |
|||
24 May 2018, 11:03 |
|
ProMiNick 24 May 2018, 15:05
revolution wrote: Just a first look at your code I see this problem: Code: apscall GetModuleHandleW,0 mov r12,data.begin str r0, [r12,wc.hInstance-data.begin] I fix it in my sources (sometime before your post), but fasmarm compilled application with window message processing still not workable. And some more qustions: If we expect that entry point is procedure where pc finaly restored from lr, we must preserve ProcessID stored in r0 (and even more we can preserve r1 with unknown meaningless value instead of preserving r0 and it is worked too) or we can trash every register end close app with ExitThread. Any idea what in r1? what for macro locals is? "locals" can`t serve all cases for which it made. Yes, values itself from locals are valid to pass as params to apscall, but ptr to that values are not. spill - is stack shadow of registers? I think more and more that mov should be overloaded by macro. We can mov to register good value (value where 24 freely shifted neibour bits are all set or all unset),we can mov to register sp or pc relative value that in range 4096 around of pc & sp, mov should handle cases when value is no good. placing pc relative values infront of each apscall I think it breaks all arm philosophy targeted to make code less branched. other compilers place this values at spaces where is no needance in skipping that data (after b branch or after restoring pc) _________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. |
|||
24 May 2018, 15:05 |
|
revolution 24 May 2018, 15:39
I think the macros should only be used for convenience when we can afford to be lazy. If you are concerned about a philosophical approach then I don't think the macros are a good solution. The macros become very complex when you consider all the variants of the CPU core instruction sets. I added an undocumented "fit" operator for when I was testing with macros to do all the complex loading and storing of all the various ways values can be used. The program then takes a very long time to assemble code of any useful length. Macros are good for small tests and short code that doesn't go into production IMO. For more realistic code not so much.
There are many ways approach the problem of loading values and constants. Macros will often constrain you to only one way, and there might be a much better way for some particular piece of code. So you might frequently find yourself manually writing sections of code to accommodate the special situation. There is nothing wrong with doing that IMO. When you need it, then you need it, so do it. But it also makes the macros kind of useless and limiting. Plus they hide a lot of what is happening underneath. In my testing I found that if one extends the macros to cover lots and lots of special cases the assembly time becomes prohibitive. Whereas a human could see the solution immediately when writing the code. In constrained environments like many ARM systems it is often necessary to take more control over the precise instructions being used. This is where macros will hurt you also. WinCE is not very popular these days. Do MS still update it? |
|||
24 May 2018, 15:39 |
|
revolution 24 May 2018, 15:56
I notice in your macro that the parameter "[wc.hInstance]" is coded as:
Code: 00000430: 00013074 V1 dw 0x00013074 ;... 00000444: E24FE01C V1 sub r14,r15,=0x430 00000448: E59EE000 V1 ldr r14,[r14] 0000044C: E50DE008 V1 str r14,[r13,-0x8] |
|||
24 May 2018, 15:56 |
|
ProMiNick 24 May 2018, 19:47
Maybe I`ll chosed smthing more modern, but when I read how to program for android I completely dissapointed in it (I waiting when dalvik technology will die). How to test WinPhone or IPhone app without device - no way. ARM LLinux is it exists? where it can be tested in qemu?
After all of that I stoped on WinCE for meeting with arm. WinCE minuses: I never hear about it in days when it was exist. I don`t know is any device in nowadays that runned such OS. WinCE pluses: I can reuse windows includes for not x86. I can emulate it. I can touch arm. Because OS targeted for ARM 4i,ARM 5i macros for it can be not so complex - instruction variance is present in coprocessor mostly (I not targeted for fpu, I already played with x86 fpu instructions, and for now trying to avoid using of them everywhere exept places where they exactly needed). P.S. Macros not only for lazy programmers, but for programmers that prefer to share its code - with macros it can be more readeble. |
|||
24 May 2018, 19:47 |
|
revolution 25 May 2018, 03:55
ProMiNick wrote: P.S. Macros not only for lazy programmers, but for programmers that prefer to share its code - with macros it can be more readeble. A good example of the lessened understanding is the invoke macro for x86. If you use the addr operator then the register edx is corrupted. There is no indication that edx is being used when looking at the source code. The following code is seriously buggy Code: mov edx,[some_pointer] invoke SomeFunction, dword[edx+4], addr esi+8 Code: mov edx,[some_pointer] invoke SomeFunction, addr esi+8, dword[edx+4] A major problem is the loading of constants. We can create literal pools and place them in convenient locations near the function code so we don't need to branch over each constant. But that requires keeping a store of them within the assembler memory and later depositing them at the end of the function. But what happens if the function is more than 4096 bytes and the code can't reach the constants? So then we start finding ways to deposit the pool after each unconditional branch (and there are lots of ways to make an unconditional branch). But we also want to keep the constants aligned and together with the each other so as not to waste the limited dcache lines with useless instruction bytes intermixed, while at the same time not wasting the limited icache lines with useless padding bytes. Add to that the possibility of sharing constants between functions. Maybe a preceding function uses a constant we need. Then we can search the previous literal pools to try and find our constant and load that instead of storing a new one. But the search is time consuming and not guaranteed to find what we need. All of these have solutions, but finding them with macros is not much fun. |
|||
25 May 2018, 03:55 |
|
ProMiNick 04 Jun 2018, 10:11
[post edited]
Atlast I make it (WinCE app with message processing) work and work correctly. First of all macros in importce.inc targeted to single imported library. I have to use 2 libraries so importce.inc patched: Code: ;FASMARM extension macros: ; ;Macros for imports section in PE file generation ; ;LIBRARY: ; ; Usage: library name1,string1,name2,string2,... ; ; name - a prefix for program labels identifying data structures ; string - a text ascii string identifying the DLL filename ; ; ;IMPORT: ; ; Usage: import name,function1,string1,function2,string2,... ; ; name - a prefix for program labels identifying data structures ; label - program label for the import ; string - the DLL exported ordinal (no matter with sign bit or not) or literal ; ;By default this file is included from "WINCE.INC". macro library [name,string] { common import.data: forward local _label if defined name#.redundant if ~ name#.redundant dw RVA name#.lookup,0,0,RVA _label,RVA name#.address end if end if name#.referred = 1 common rw 5 forward if defined name#.redundant if ~ name#.redundant _label db string,0 rb RVA $ and 1 end if end if } macro import name,[label,string] { common rb (- rva $) and 3 if defined name#.referred name#.lookup: forward if used label if string eqtype '' local _label dw RVA _label else dw 80000000h or string end if end if common if $ > name#.lookup name#.redundant = 0 dw 0 else name#.redundant = 1 end if name#.address: forward if used label name#.#label dw ? end if common if ~ name#.redundant dw 0 end if forward if used label label: if $+8-name#.#label<$0FFF ldr pc,[pc,name#.#label-$-8] else ldr r12,[pc] ldr pc,[r12] dw name#.#label end if end if forward if used label & string eqtype '' _label dh 0 db string,0 rb RVA $ and 1 end if common end if } and declaration of 2nd library (its imports that I know): COMMCTRL.INC: Code: import commctrl,\ CommandBar_Create,'CommandBar_Create',\ CommandBar_AddAdornments,'CommandBar_AddAdornments',\ CommandBar_InsertMenubarEx,'CommandBar_InsertMenubarEx',\ CommandBar_Height,'CommandBar_Height' and source file itself (WINCE.ASM): Code: format PE GUI entry Start include 'WINCE.INC' struct POINT x dw ? y dw ? ends struct WNDCLASS style dw ? lpfnWndProc dw ? cbClsExtra dw ? cbWndExtra dw ? hInstance dw ? hIcon dw ? hCursor dw ? hbrBackground dw ? lpszMenuName dw ? lpszClassName dw ? ends struct MSG hwnd dw ? message dw ? wParam dw ? lParam dw ? time dw ? pt POINT ends section '.text' code readable executable Start: stmfd sp!,{r0,lr} sub sp,sp,$20 mov r5,r0 ldr r6,[pc+.local.lpwc-$-8] str r5,[r6+WNDCLASS.hInstance] apscall RegisterClassW,r6 mov r1, r0,lsl#16 movs r0, r1,lsr#16 addeq sp,sp,$20 ldmeqfd sp!,{r0,pc} apscall GetSystemMetrics,0 ldr r1,[pc+.local.lpwidth-$-8] str r0,[r1] mov r4,r0 apscall GetSystemMetrics,1 ldr r1,[pc+.local.lpheight-$-8] str r0,[r1] mov r7,r0 mov r0,0 str r0,[sp+$1C] str r5,[sp+$18] str r0,[sp+$14] str r0,[sp+$10] str r7,[sp+$0C] str r4,[sp+$08] str r0,[sp+$04] str r0,[sp+$00] mov a4,$10000000 ldr a3,[pc+.local.lptitle-$-8] ldr a2,[r6+WNDCLASS.lpszClassName] ;mov a1,r0 bl CreateWindowExW movs r4,r0 addeq sp,sp,$20 ldmeqfd sp!,{r0,pc} apscall ShowWindow,r0,r9 apscall UpdateWindow,r4 .msg_loop: mov r3,0 mov r2,0 mov r1,0 add r0,pc,.msg_loop.msg-$-8 bl GetMessageW cmp r0,0 beq .end_loop add r0,pc,.msg_loop.msg-$-8 bl TranslateMessage add r0,pc,.msg_loop.msg-$-8 bl DispatchMessageW b .msg_loop .msg_loop.msg MSG .end_loop: ldr r0,[pc+.msg_loop.msg.wParam-$-8] add sp,sp,$20 ldmfd sp!,{r0,pc} ;end Start body .local: .local.lpwc dw wc .local.lptitle dw _title .local.lpwidth dw width .local.lpheight dw height ;end pc relative locals of Start WindowProc: ;proc WindowProc nospil uses[R4-R8,R11,LR},hwnd,wmsg,wparam,lparam stmfd sp!,{r4-r8,r11,lr} cmp a2,2 moveq r0,0 bleq PostQuitMessage moveq r0,0 ldmeqfd sp!,{r4-r8,r11,pc} cmp a2,1 bleq .wmcreate apscall DefWindowProcW,r0,r1,r2,r3 ldmfd sp!,{r4-r8,r11,pc} .wmcreate: ldr r6,[pc+Start.local.lpwc-$-8] mov r1,r0 ldr r0,[r6,WNDCLASS.hInstance] mov r2,$3E8 bl CommandBar_Create apscall CommandBar_AddAdornments,r0,0,0 ldmfd sp!,{r4-r8,r11,pc} ;end WindowProc body .local: .local.lpwc dw wc ;end pc relative locals of WindowProc section '.data' data readable writeable wc WNDCLASS 1,WindowProc,0,0,0,0,0,5,0,_class _class du 'FASMWINCE',0 _title du 'WinCE program template',0 align 4 width dw ? height dw ? section '.idata' import readable writeable library coredll,'COREDLL.DLL',\ commctrl,'commctrl.dll' include 'APICE\COREDLL.INC' include 'APICE\COMMCTRL.INC' for now it is mix of macroed & pure code _________________ I don`t like to refer by "you" to one person. My soul requires acronim "thou" instead. |
|||
04 Jun 2018, 10:11 |
|
ProMiNick 08 Jun 2018, 07:28
Question about ARM not relative to WinCE:
ARM_..._32 and ARM_..._64 are completely independent sets of instructions (like x86 & Intel64), or some instructions (maybe fpu ones) are subsetted (like x86 almost fully subset of AMD64). registers in ARM32 are r with index, in ARM64 x with index. Question about processor directive - Are some subsets of instructions are included in other subsets (v7 included in v8 or something else) or they completely independent subsets? |
|||
08 Jun 2018, 07:28 |
|
revolution 08 Jun 2018, 10:58
For the 32 vs 64 modes, the instruction encoding is completely different. No overlap.of encoding anywhere. This is true for both the integer and floating point.
For fasmarm, the instruction sets enabled by the processor directive, and the coprocessor directive, do not overlap anywhere. You have to enable each one independently for your CPU. |
|||
08 Jun 2018, 10:58 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.