Author Topic: Bug in Prolog macro interpretation?  (Read 3151 times)

jj2007

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Bug in Prolog macro interpretation?
« on: July 21, 2016, 08:14:18 AM »
This affects the whole Watcom family, including AsmC:
Code: [Select]
OPTION PROLOGUE:MyPrologue
OPTION EPILOGUE:MyEpilogue
WndProc proc hWnd, uMsg, wParam:WPARAM, lParam:LPARAM

if 0 ; GOOD, this one works
LOCAL psvar:PAINTSTRUCT, rc:RECT

else ; BAD, this one fails
LOCAL rc:RECT, psvar:PAINTSTRUCT
endif

  ; int 3
  mov edx, hWnd
  mov rc.left, 11111111h
  mov rc.right, 33333333h
if 0
00401006         ³.  CC                 int3
00401007         ³.  8B55 08            mov edx, [ebp+8]
Watcom family:
0040100A         ³.  C745 0E 11111111   mov dword ptr [ebp+0E], 11111111
00401011         ³.  C745 16 33333333   mov dword ptr [ebp+16], 33333333
MASM:
0040100A         ³.  C745 F0 11111111   mov dword ptr [ebp-10], 11111111
00401011         ³.  C745 F8 33333333   mov dword ptr [ebp-8], 33333333
endif
  invoke crt_printf, cfm$("WP2 Args received: %x, %x, %x, %x, rcl=%x, rcr=%x\n"),  hWnd, uMsg, wParam, lParam, rc.left, rc.right
  ret
WndProc endp

Full code attached, as plain Masm32.

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Bug in Prolog macro interpretation?
« Reply #1 on: July 22, 2016, 01:49:50 AM »
Apparently the return value from the prologue macro needs to be expanded in this case. Try this:
Code: [Select]
  EXITM %localbytes


jj2007

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Bug in Prolog macro interpretation?
« Reply #3 on: July 22, 2016, 04:38:36 AM »
Apparently the return value from the prologue macro needs to be expanded in this case. Try this:
Code: [Select]
  EXITM %localbytes

Perfect :t

Not entirely compatible with MASM, but in this case, it doesn't matter at all.

P.S.: Just found the reason for this strange behaviour. Insert this into the prolog:
Code: [Select]
  pTmp$ CATSTR <** ex$ >, <localbytes>
  % echo pTmp$
  pTmp$ CATSTR <** ex# >, %localbytes
  % echo pTmp$
  EXITM <localbytes>

This shows the following for the example code:
Code: [Select]
** ex$ 050H
** ex# 80

And guess what? The ebp offset is 80-50=30 bytes too high 8)

Btw Val() would return 80 for both exit strings :icon_mrgreen:
« Last Edit: July 22, 2016, 10:24:45 AM by jj2007 »

jj2007

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Bug in Prolog macro interpretation?
« Reply #4 on: September 06, 2016, 08:01:33 AM »
I stumbled into a weird behaviour of the prolog macro: It appears to kick in several lines AFTER the sometest proc.

Code: [Select]
tmpLine$ CATSTR <** This is line >, %@Line, < **>
% echo tmpLine$

WndProc proc <cb cs> uses rsi rdi rbx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL ps:PAINTSTRUCT
if jbCompStyle ; <<<<<<<<<<<<<< a variable set in the prolog: 1 if cs is present in userparms
echo ******* ON A
else
echo ******* OFF A
endif
if 1                   ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  cmp uMsg, WM_CREATE
  jne not_create
endif
if jbCompStyle
echo ******* ON B
else
echo ******* OFF B
endif

Output for if 1 (note that the echo ## PROLOG is inside the prologue macro!):
Code: [Select]
** This is line 47 **
******* OFF A
## PROLOG, line 57: WndProc: args+locals=010H+040H=80, _flags=03H, _userparms=cb cs
******* ON B

Output for if 0:
Code: [Select]
** This is line 47 **
******* OFF A
******* OFF B
## PROLOG, line 65: WndProc: args+locals=010H+040H=80, _flags=03H, _userparms=cb cs

So the output from the prologue macro moves even further down if the
Code: [Select]
  cmp uMsg, WM_CREATE
  jne not_create
are disabled ::)

For me, it makes absolutely no sense that PROLOGUE kicks in after the echo A. Any ideas?
Btw same behaviour for all assemblers tested...
« Last Edit: September 06, 2016, 09:08:36 AM by jj2007 »

habran

  • Member
  • *****
  • Posts: 1175
    • uasm
Re: Bug in Prolog macro interpretation?
« Reply #5 on: September 06, 2016, 09:35:36 AM »
Why you don't use this:
WndProc PROC FRAME uses rsi rdi rbx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
and everything will be set correctly ::)
Cod-Father

jj2007

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Bug in Prolog macro interpretation?
« Reply #6 on: September 06, 2016, 09:45:37 AM »
Does that answer my question, Habran?

habran

  • Member
  • *****
  • Posts: 1175
    • uasm
Re: Bug in Prolog macro interpretation?
« Reply #7 on: September 06, 2016, 09:54:04 AM »
I don't see from your source that you use any prologue, do you?
Cod-Father

jj2007

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Bug in Prolog macro interpretation?
« Reply #8 on: September 06, 2016, 10:00:54 AM »

habran

  • Member
  • *****
  • Posts: 1175
    • uasm
Re: Bug in Prolog macro interpretation?
« Reply #9 on: September 06, 2016, 10:29:07 AM »
I see that you are using 32 registers for prolog
are you sure you know what are you doing?
Can you post disassembly of your code to see what you produced.
To write a proper PROLOGUE and EPILOGUE you must know exactly what are yo doing, I've never written one because the one available in HJWasm was doing the job properly.
Now you are pushing me to study about it, you are ruthless more than Johnsa, I need a break ::)
Cod-Father

jj2007

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Bug in Prolog macro interpretation?
« Reply #10 on: September 06, 2016, 11:03:31 AM »
I see that you are using 32 registers for prolog
are you sure you know what are you doing?
Can you post disassembly of your code to see what you produced.
To write a proper PROLOGUE and EPILOGUE you must know exactly what are yo doing, I've never written one because the one available in HJWasm was doing the job properly.
Now you are pushing me to study about it, you are ruthless more than Johnsa, I need a break ::)

OK, here is an excerpt from the Win64 template - the nops to make clear where the WndProc starts:
Code: [Select]
WinMain endp
nop
nop
nop
nop
WndProc proc <cb cs> uses rsi rdi rbx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL ps:PAINTSTRUCT
  cmp uMsg, WM_CREATE
  jne not_create
  int 3
reStyle=WS_VISIBLE or WS_CHILD or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL or ES_AUTOHSCROLL or ES_AUTOVSCROLL or ES_NOHIDESEL
jinvoke LoadLibrary, Chr$("RichEd20") ; we add a RichEdit control
ID_EDIT=111
jinvoke CreateWindowEx, WS_EX_CLIENTEDGE, Chr$("RichEdit20A"), NULL, reStyle, 0, 0, 1, 1, hWnd, ID_EDIT, wcx.hInstance, NULL

Translates to:
Code: [Select]
00000001400011D9  | 90                         | nop                                |
00000001400011DA  | 90                         | nop                                |
00000001400011DB  | 55                         | push rbp                           |
00000001400011DC  | 48 8B EC                   | mov rbp, rsp                       |
00000001400011DF  | 48 89 4D 10                | mov qword ptr ss:[rbp+10], rcx     |
00000001400011E3  | 48 89 55 18                | mov qword ptr ss:[rbp+18], rdx     |
00000001400011E7  | 4C 89 45 20                | mov qword ptr ss:[rbp+20], r8      |
00000001400011EB  | 4C 89 4D 28                | mov qword ptr ss:[rbp+28], r9      |
00000001400011EF  | 48 81 EC F0 00 00 00       | sub rsp, F0                        |
00000001400011F6  | 48 89 75 D8                | mov qword ptr ss:[rbp-28], rsi     |
00000001400011FA  | 48 89 7D E0                | mov qword ptr ss:[rbp-20], rdi     |
00000001400011FE  | 48 89 5D E8                | mov qword ptr ss:[rbp-18], rbx     |
0000000140001202  | 83 7D 18 01                | cmp dword ptr ss:[rbp+18], 1       |
0000000140001206  | 0F 85 7C 01 00 00          | jne skeldualgui64.140001388        |
000000014000120C  | CC                         | int3                               |
000000014000120D  | 48 8D 0D 6D 1E 00 00       | lea rcx, qword ptr ds:[140003081]  | 140003081:"RichEd20"
0000000140001214  | 48 89 0C 24                | mov qword ptr ss:[rsp], rcx        |
0000000140001218  | FF 15 9E 24 00 00          | call qword ptr ds:[<&LoadLibraryA> |
000000014000121E  | 45 33 D2                   | xor r10d, r10d                     |
0000000140001221  | 4C 89 54 24 58             | mov qword ptr ss:[rsp+58], r10     |
0000000140001226  | 4C 8B 15 EF 1D 00 00       | mov r10, qword ptr ds:[14000301C]  |
000000014000122D  | 4C 89 54 24 50             | mov qword ptr ss:[rsp+50], r10     |
0000000140001232  | 41 BA 6F 00 00 00          | mov r10d, 6F                       |
0000000140001238  | 4C 89 54 24 48             | mov qword ptr ss:[rsp+48], r10     |
000000014000123D  | 4C 8B 55 10                | mov r10, qword ptr ss:[rbp+10]     |
0000000140001241  | 4C 89 54 24 40             | mov qword ptr ss:[rsp+40], r10     |
0000000140001246  | 41 BA 01 00 00 00          | mov r10d, 1                        |
000000014000124C  | 4C 89 54 24 38             | mov qword ptr ss:[rsp+38], r10     |
0000000140001251  | 41 BA 01 00 00 00          | mov r10d, 1                        |
0000000140001257  | 4C 89 54 24 30             | mov qword ptr ss:[rsp+30], r10     |
000000014000125C  | 45 33 D2                   | xor r10d, r10d                     |
000000014000125F  | 4C 89 54 24 28             | mov qword ptr ss:[rsp+28], r10     |
0000000140001264  | 45 33 D2                   | xor r10d, r10d                     |
0000000140001267  | 4C 89 54 24 20             | mov qword ptr ss:[rsp+20], r10     |
000000014000126C  | 41 B9 C4 01 30 50          | mov r9d, 503001C4                  |
0000000140001272  | 4C 89 4C 24 18             | mov qword ptr ss:[rsp+18], r9      |
0000000140001277  | 45 33 C0                   | xor r8d, r8d                       |
000000014000127A  | 4C 89 44 24 10             | mov qword ptr ss:[rsp+10], r8      |
000000014000127F  | 48 8D 15 04 1E 00 00       | lea rdx, qword ptr ds:[14000308A]  | 14000308A:"RichEdit20A"
0000000140001286  | 48 89 54 24 08             | mov qword ptr ss:[rsp+8], rdx      |
000000014000128B  | B9 00 02 00 00             | mov ecx, 200                       |
0000000140001290  | 48 89 0C 24                | mov qword ptr ss:[rsp], rcx        |
0000000140001294  | FF 15 E2 23 00 00          | call qword ptr ds:[<&CreateWindowE |
000000014000129A  | 48 89 05 C3 20 00 00       | mov qword ptr ds:[140003364], rax  |

Does that look OK? Full source attached, requires MasmBasic of today (I solved the mystery of the PROLOG macro :biggrin:); the source assembles as 64-bit or 32-bit code, with ML/ML64, HJWasm and AsmC. Note the int 3, the exe is meant to be launched with a debugger.