NO

Author Topic: Bad jump  (Read 1708 times)

Grincheux

  • Guest
Bad jump
« on: July 07, 2021, 06:48:33 pm »
When I call the "DeleteFiles" function, if I select more than one file, there is something strange that I can't understand.
The problem is the CALL to MessageBoxA. It does not display the good message and returns into an other function "Error"
Code: [Select]
@DF_MultiSelect :
                     MOV      RCX,hWndMain + RIP
                     MOV      RDX,OFFSET szDelete_Warning_MultiSel
                     MOV      R8,OFFSET szDelete_Confirm
                     MOV      R9D,MB_YESNO OR MB_ICONQUESTION OR MB_APPLMODAL OR MB_TOPMOST OR MB_SETFOREGROUND
                     CALL   MessageBoxA

                     CMP      EAX,IDYES                  ; The user clicked "NO"
                     JNE      @DF_Exit
I join the asm code because I don't understand. For the complete project use https://www.mediafire.com/file/pt8i7v2vo6eqers/Display.7z/file.
Please help me I don't know what to do.
Thank You (in advance)
« Last Edit: July 07, 2021, 06:50:19 pm by Grincheux »

Offline John Z

  • Member
  • *
  • Posts: 533
Re: Bad jump
« Reply #1 on: July 08, 2021, 10:38:53 am »
I'll download shortly to see if my rusty skills can see anything.

As an initial GUESS you have a memory corruption issue.  Presupposing the everything functions ok with one filename to delete I surmise that passing in multiple filenames at once is corrupting memory leading to the failure of the messagebox and the incorrect 'return' location. 

Just a guess - but if it were my code that is where I would start.


Respectfully,
John Z

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1941
Re: Bad jump
« Reply #2 on: July 08, 2021, 11:32:20 am »
Not sure, but maybe that you left something on the stack.
You like very much a programming style using what are called 'coroutines' jumping between different functions.
This is a risky method unless much care is taken about stack contents and memory code layout (the last can't be anyway in full control).
I.e. the following code:
Code: [Select]
; ############################################
; ### Select the next file in the listview ###
; ############################################

@DF_ShowPrevious :
MOV RCX,hListView + RIP
MOV RDX,LVM_ENSUREVISIBLE
MOV R8D,_Lvi.iItem
XOR R9D,R9D
CALL SendMessageA

LEA R9,_Lvi
MOV [R9].LVITEM._mask,LVIF_STATE
MOV [R9].LVITEM.iState,LVIS_SELECTED OR LVIS_FOCUSED
MOV [R9].LVITEM.stateMask,LVIS_SELECTED OR LVIS_FOCUSED

MOV RCX,hListView + RIP
MOV RDX,LVM_SETITEMSTATE
MOV R8D,_Lvi.iItem
CALL SendMessageA

; ####################################
; ### Update the listview and Exit ###
; ####################################

MOV RCX,hListView + RIP
MOV RDX,LVM_UPDATE
MOV R8D,_Lvi.iItem
XOR R9D,R9D
MOV RAX,OFFSET @DF_Exit
PUSH RAX
JMP SendMessageA
; _______________________________________________________________________________________
ALIGN 16

; ============================================
; === The user selected more than one file ===
; ============================================

@DF_MultiSelect :
MOV RCX,hWndMain + RIP
MOV RDX,OFFSET szDelete_Warning_MultiSel
MOV R8,OFFSET szDelete_Confirm
MOV R9D,MB_YESNO OR MB_ICONQUESTION OR MB_APPLMODAL OR MB_TOPMOST OR MB_SETFOREGROUND
CALL MessageBoxA

CMP EAX,IDYES ; The user clicked "NO"
JNE @DF_Exit

; =======================================
; === Search which items are selected ===
; =======================================

; _______________________________________________________________________________________
ALIGN 16
@DF_NextFile :
MOV RCX,hListView + RIP

You reach 'DF_ShowPrevious' by jumping from a different procedure after you pushed a return address, through RAX, on the stack. But executing the code you pass through an 'Align 16'. It is acceptable to suppose that the compiler will fill the gap using 'nop's, but the linker can do something different.

Very hard to follow the full assembler flow, it requires time and concentration, so I can only suggest you to carefully check each instruction, the stack content between any jump, eventual var_arg functions (i.e. sqlite3_snprintf) that can interest, in some cases, the stack too, and the filling of memory spaces after Align directives.
Good luck...  :)

Grincheux

  • Guest
Re: Bad jump
« Reply #3 on: July 08, 2021, 01:05:22 pm »
I have found the problem.
It is not where I have shown in the last post. It is because at the same time I get a WM_ACTIVATE message and when debugging it was the code of an other routine "Refresh" that the debugger displayed. I thought there was a problem with local labels so I have renamed all of them.
Now I don't treat WM_ACTIVATE and this problem is solved.
Why did I received WM_ACTIVATE? Because when selecting the images whith the mouse it automatically sends WM_ACTIVATE.
Why did I treat WM_ACTIVATE? Because I have an option to launch the image editor and when it is finished I wanted to get the size of the images.
I know there is a window function that called a callback to tell which file/folder has been modified. I don't remember which.
I think the solution is with this function.


Thank You for your help.

Offline John Z

  • Member
  • *
  • Posts: 533
Re: Bad jump
« Reply #4 on: July 08, 2021, 01:30:49 pm »
Thumbs Up 3x  :)


John Z


Grincheux

  • Guest
Re: Bad jump
« Reply #6 on: July 09, 2021, 08:03:49 am »
Frankie
Quote
[/size][size=78%]You reach 'DF_ShowPrevious' by jumping from a different procedure after you pushed a return address, through RAX, on the stack. But executing the code you pass through an 'Align 16'. It is acceptable to suppose that the compiler will fill the gap using 'nop's, but the linker can do something different.[/size]



I would use a "CALL" rather tan a "JUMP" if I would be certain the compiler inserrts "NOPs" but this always is not the case.
And consider the following cases:


Code: [Select]
CALL Routine_1
JMP Label_1


CALL ROUTINE_2
RET


It is quicker to replace the CALL with the following:


Code: [Select]
MOV RAX,OFFSET Label_1
PUSH RAX
JMP Routine_1


MOV RAX,OFFSET Adr_Ret
PUSH RAX
JMP Routine_2


If the stack is bad filled the JMPs to simulate the CALLs will go anywhere in memory, that will be corrected since the first debugging session.


two other thing I use:
- Use XMM registers to replace a "PUSH".
- Return result can also be done in setting the result into an XMM register rather than EAX. Or EAX is used to return an other result.


Thak You Frankie for your comments.


Grincheux






Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1941
Re: Bad jump
« Reply #7 on: July 09, 2021, 12:05:59 pm »
Grincheux, as I already told many times, programming is also the freedom to create the code as you like if it fits the purpose.
But sometime you have to be cautious about some tricky constructs, it isn't only a readability reason, but a technical problem.
I'm sure that your code works, but you can't expect that some meta commands give specific solutions.

Grincheux

  • Guest
Re: Bad jump
« Reply #8 on: July 09, 2021, 05:05:56 pm »
You are right but in assembly for the same command there are, sometimes, many solutions:
NOP => XOR RAX,RAX or ADD [RBX+RSI],00 or ...
MUL => MUL Or IMUL or LEA or SHL
MOV REG,0 => SUB REG,REG, XOR REG,REG or DEC REG or MUL by Magic Number or ADC... or SBB
DIV => IDIV or MUL or SHR
CMP => CMOcc
CALL => JMP

Even if the result is the same the flags set can be different and it is function what you want to do, and this the more difficult thing.
Example :
MOV RAX,-1
MOV RBX,2

SHR RAX,1
ADC RBX,RBX => will give 5 rather than 4

On other reaason is for getting parallelisation.
Move certain instructions before other to have the two instructions executed at the same time
...

Read INTEL, AMD  manuals.

And a last and most important advice that PELLE gave me is first of all "HAVE A GOOD ALGORITHM"

This post is the kind of discussion we would have in the forum, not between us.
I change of subject, what is your pronostic for ITALIA vs ENGLAND
I expect, I hope ITALIA 2 / ENGLAND 1.

I hope they will not make the same thing tat in 1966!

Thank You for the comments, I appreciate.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1941
Re: Bad jump
« Reply #9 on: July 09, 2021, 09:35:18 pm »
Grincheux let me disagree about the multiple way to do something in assembler, in many cases it isn't true.
As in C each instruction influence flags and change registers. One for all 'NOP' doesn't change anything in processor context. On the other hand 'XOR EAX,EAX' modify EAX register and change flags. Similar "side effects", as they are called in C, are present in all other examples you made, last the 'JMP' instead of 'CALL' that requires a register to push the address on the stack adding the load register time plus the push that are in one microcode stream for a call.
I have read intel manuals, and from many other processors, long time ago.  ;D
The choice of one coding vs the other depends on what is more functional in that case, but shouldn't be a fix choice.
Anyway it is up to you, if you like it this way ... keep you happy.  ;)

About Italy vs Engand I don't express (you know italians are superstitious  ;D)
Anyway I'm very disappointed for Denmark, England literally snatched the victory. Without words...  >:(

Grincheux

  • Guest
Re: Bad jump
« Reply #10 on: July 09, 2021, 10:08:38 pm »
Ok


NOP => XCHG RAX,RAX

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1941
Re: Bad jump
« Reply #11 on: July 10, 2021, 12:07:39 am »
Ok
NOP => XCHG RAX,RAX
;D ;D ;D ;D ;D
One more?  8)

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1941
Re: Bad jump
« Reply #12 on: July 12, 2021, 12:41:56 pm »
                   to
Football come Rhome!  ;)
« Last Edit: July 14, 2021, 09:52:36 am by frankie »

Grincheux

  • Guest
Re: Bad jump
« Reply #13 on: July 12, 2021, 04:45:28 pm »
B R A V O to the Italian football team

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 1941
Re: Bad jump
« Reply #14 on: July 14, 2021, 09:58:10 am »
 ;)