flat assembler
Message board for the users of flat assembler.

flat assembler > Non-x86 architectures > WinCE & ARM questions

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
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
It looks like 1 instruction shorter, but maybe I missed smthing and your variant is shortest possible?

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
https://drive.google.com/open?id=1Qe9oUFpOh_NhdM4r8i3jQoPOQXvCK4S0

_________________
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
Post 15 May 2018, 13:07
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
ProMiNick wrote:
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.
In ARM mode the value of PC is the current instruction + 8. In Thumb mode it is a bit more complex. A single instruction can't access immediate memory offsets further than 4096 bytes away.
ProMiNick wrote:
why second part not so:
Code:
ldr pc,[pc] nop dw _#function
It looks like 1 instruction shorter, but maybe I missed smthing and your variant is shortest possible?
It is a pointer to a pointer. The _#function value is not a pointer to the OS function, it is an intermediate pointer to the pointer to the OS function. The OS linker/loader will only link one pointer per function, we can't coax it to make new pointers each time we call a function. Since we can't reach the offset in one instruction, we have to make it a pointer to the pointer.

Another way to code it if you have the MOVW instruction available and the address is numerically higher but less than 2^16 bytes distant is this:
Code:
movw r12,_#function-$-12 ldr pc,[pc,r12]
ProMiNick wrote:
And how you got coredll.inc it documented somewhere or you test this dll in wince, or extract it from *.BIN image?
I have no documentation on coredll.dll. I reverse engineered the functions.

But, I wonder if there are any systems out there that still use WinCE? Maybe three people in the world use it now?
Post 15 May 2018, 13:47
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
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
in common case:
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?
Post 16 May 2018, 10:12
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
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)?
The idea is that the literal pool is placed close the the code where the values are needed. It you place it too far away (more than 4096 bytes) then the instructions for accessing it become much more complex. In ARM code this is normal. The caches are designed to operate with this functionality in mind.

"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?
In ARM speak it is ADR. It is synthesized by the assembler, and is documented in the ARM ARM.
Post 16 May 2018, 10:34
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
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]
and in
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
still don`t

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'
Post 16 May 2018, 13:56
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
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.
Post 16 May 2018, 14:08
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
patched PROCAPS.INC:
Code:
macro def_ustring labl,[string] {common labl dU string} macro def_astring labl,[string] {common labl dB string}
added
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: \{
added
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
added
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 \{
added
Code:
if defined ..arg ADD lr,pc,..arg-$-8 LDR lr,[lr] else
Code:
LDR lr,[address]
added
Code:
end if

all rest remain untouched

compiled successfuly, but


Description:
Filesize: 184.05 KB
Viewed: 1332 Time(s)

wince.jpg



_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 16 May 2018, 14:48
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
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?


Description:
Download
Filename: PROCAPS.INC
Filesize: 20.44 KB
Downloaded: 28 Time(s)


_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 17 May 2018, 23:48
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
Can you attach a full set of sources for the code you assembled?. I'll see what I can find.
Post 18 May 2018, 06:56
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
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!)


Description: I already cleared in it all hll shit around of start - so it is still normal work. & listing inside
Download
Filename: Utilities.zip
Filesize: 30.35 KB
Downloaded: 26 Time(s)

Description: my fasmarm with corrections in procaps
Download
Filename: FASMARM.zip
Filesize: 736.26 KB
Downloaded: 27 Time(s)


_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 18 May 2018, 10:17
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
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'
problem apscall dos`n operate with locals defined via virtual not throw local. How make proc wrapper that makes exatctly that "STMFD SP!, {R0,LR};SUB SP, SP, #0x70"?


Description:
Download
Filename: search3.zip
Filesize: 2.38 KB
Downloaded: 20 Time(s)


_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 23 May 2018, 10:39
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
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]
R12 is not preserved in the ARM procedure call standard. So expect it to be corrupted by the call.
Post 24 May 2018, 11:03
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
revolution wrote:
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]
R12 is not preserved in the ARM procedure call standard. So expect it to be corrupted by the call.

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.
Post 24 May 2018, 15:05
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
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?
Post 24 May 2018, 15:39
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
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]
So it doesn't load the value from [wc.hInstance], it loads the address of wc.hInstance. You will need to load the address first and then load the value, a pointer to a pointer.
Post 24 May 2018, 15:56
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
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.
Post 24 May 2018, 19:47
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
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.
Perhaps you are correct that it will be more readable, but I think it is also less understandable about what the CPU is asked to do. The macros make it more like HLL and obscure the link to the underlying instructions. Usually an HLL will make sure everything works as intended, but for assembly coders things are not so well controlled.

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
... but this code is perfectly fine
Code:
mov edx,[some_pointer] invoke SomeFunction, addr esi+8, dword[edx+4]
This was part of my previous experiment where I tried to detect all the various problems and find ways around them. If someone used R12 as a source operand then I could use R14 as a temporary, and if someone used R14 as a source operand then I could use R12. But what happens when both R12 and R14 are used as sources? There are ways to do it that involve the stack but the code quickly gets ugly, and the assembly time balloons out of control with the macros trying to detect all this kind of stuff and changing the code to accommodate it.

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.
Post 25 May 2018, 03:55
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
[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.
Post 04 Jun 2018, 10:11
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 160
Location: Russian Federation, Sochi
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?
Post 08 Jun 2018, 07:28
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15871
Location: 162173 Ryugu
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.
Post 08 Jun 2018, 10:58
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 2004-2018, Tomasz Grysztar.

Powered by rwasa.