Author Topic: @dothis/@whilethis for ML64 (or every other)  (Read 220 times)

HSE

  • Member
  • *****
  • Posts: 2362
  • AMD 7-32 / i3 10-64
@dothis/@whilethis for ML64 (or every other)
« on: January 10, 2023, 10:46:39 AM »
Hi all!!

Happen that I was translating a procedure from Java that have a classical C++ loop:
Code: [Select]
do{
  ยทยทยท
}
while condition

Very easy to adapt macros derived from Mabdelouahab's Macros 2017 to this:
Code: [Select]
    mov rax, 5
    mov value1, rax
    @dothis
        conout str$(rax),lf
        .if value1 }= 10
            @breakthis
        .endif
       
        mov rax, value1
        add rax, 1
        mov value1, rax
    @whilethis  rax gt 0

Like before the example test integers (in 32 and 64 bits). To test floating point numbers require SmplMath for syntax.

Thanks in advance for testing macros, HSE.
Equations in Assembly: SmplMath

jj2007

  • Member
  • *****
  • Posts: 13657
  • Assembly is fun ;-)
    • MasmBasic
Re: @dothis/@whilethis for ML64 (or every other)
« Reply #1 on: January 10, 2023, 12:39:40 PM »
Code: [Select]
@whilethis eax ua 0 && ebx ua 3
What does "ua" mean?

HSE

  • Member
  • *****
  • Posts: 2362
  • AMD 7-32 / i3 10-64
Re: @dothis/@whilethis for ML64 (or every other)
« Reply #2 on: January 10, 2023, 02:40:10 PM »
Code: [Select]
@whilethis eax ua 0 && ebx ua 3
What does "ua" mean?

Unsigned above. See FlowControl.inc. It's mostly what we talk with Hutch and Mab in that thread.
Equations in Assembly: SmplMath

Biterider

  • Member
  • *****
  • Posts: 1076
  • ObjAsm Developer
    • ObjAsm
Re: @dothis/@whilethis for ML64 (or every other)
« Reply #3 on: January 10, 2023, 05:56:31 PM »
Hi HSE
Here it works perfectly well  :thumbsup:

Biterider

jj2007

  • Member
  • *****
  • Posts: 13657
  • Assembly is fun ;-)
    • MasmBasic
Re: @dothis/@whilethis for ML64 (or every other)
« Reply #4 on: January 10, 2023, 08:23:07 PM »
Unsigned above

Ok, so it's the equivalent of ja :thumbsup:

Works fine here. Under the hood:
Code: [Select]
  int 3
  @dothis
; print str$(eax), 13, 10
mov eax, v1
sub eax, 1
mov v1, eax
  @whilethis eax ua 0 && ebx ua 3
  nops 4
  .Repeat
; print str$(eax), 13, 10
mov eax, v1
sub eax, 1
mov v1, eax
  .Until eax<=0 || ebx<=3
  nops 4

Code: [Select]
0040103E  |.  CC            int3
0040103F  |>  8B45 FC       /mov eax, [local.1]                      ; @dothis
00401042  |.  83E8 01       |sub eax, 1
00401045  |.  8945 FC       |mov [local.1], eax
00401048  |.  83F8 00       |cmp eax, 0
0040104B  |.  76 07         |jbe short 00401054
0040104D  |.  83FB 03       |cmp ebx, 3
00401050  |.  76 02         |jbe short 00401054
00401052  |.^ EB EB         \jmp short 0040103F                      ; @whilethis end
00401054  |>  90            nop
00401055  |.  90            nop
00401056  |.  90            nop
00401057  |.  90            nop
00401058  |>  8B45 FC       /mov eax, [local.1]                      ; .Repeat
0040105B  |.  83E8 01       |sub eax, 1
0040105E  |.  8945 FC       |mov [local.1], eax
00401061  |.  83F8 00       |cmp eax, 0
00401064  |.  76 05         |jbe short 0040106B
00401066  |.  83FB 03       |cmp ebx, 3
00401069  |.^ 77 ED         \ja short 00401058                       ; .Until
0040106B  |>  90            nop
0040106C  |.  90            nop
0040106D  |.  90            nop
0040106E  |.  90            nop

Btw UAsm throws Error A2101: Macro nesting level too deep (but it works fine with AsmC)

HSE

  • Member
  • *****
  • Posts: 2362
  • AMD 7-32 / i3 10-64
Re: @dothis/@whilethis for ML64 (or every other)
« Reply #5 on: January 11, 2023, 12:11:21 AM »
so it's the equivalent of ja :thumbsup:

That depend how you build the loop. In first example the negation is used and you have an extra jump, because is the better way for complex conditions.


Btw UAsm throws Error A2101: Macro nesting level too deep (but it works fine with AsmC)

 :thumbsup: UAsm have internal macros that can have conflicts with other macros. Usually you have to disable that when using your own macros:
Code: [Select]
uasm32_2.56 /c /coff -nomlib DoThis32.asm
Equations in Assembly: SmplMath

jj2007

  • Member
  • *****
  • Posts: 13657
  • Assembly is fun ;-)
    • MasmBasic
Re: @dothis/@whilethis for ML64 (or every other)
« Reply #6 on: January 11, 2023, 12:16:21 AM »
In first example the negation is used and you have an extra jump, because is the better way for complex conditions.

I wrote ja but obviously here it's the negation, i.e. jbe, present twice in both the macro and the .repeat example.
Btw why is an extra jump "the better way for complex conditions"? It just means 3 bytes more than the .repeat ... .until example, and I doubt it's any faster (but that could be tested, of course)

Quote
UAsm have internal macros that can have conflicts with other macros. Usually you have to disable that when using your own macros:
Code: [Select]
uasm32_2.56 /c /coff -nomlib DoThis32.asm

Good to know, thanks :thup:

HSE

  • Member
  • *****
  • Posts: 2362
  • AMD 7-32 / i3 10-64
Re: @dothis/@whilethis for ML64 (or every other)
« Reply #7 on: January 11, 2023, 12:56:59 AM »
Btw why is an extra jump "the better way for complex conditions"?

It's easy  :biggrin: That part was writed years ago by Mabdelouahab, perhaps could be improved.

But 3 bytes is nothing when you are making complex floting point numbers conditions with code so clean. 

I have not problem to pay 3 bytes even in simple cases:
Code: [Select]
        @dothis
            inc m
            fSlv8 d5 = [xsi].d[xbx*8];
            mov xax, mj1
            fSlv8 d6 = ([xsi].d[xax*8] - d5) / (2.0 * [xsi].e[xbx*8])
            fSlv8 d7 = (d6^2+ 1.0)^0.5
            .if fLT(d6, 0.0)
                fSlv8 d7 = -d7
            .endif
            fSlv8 [xsi].d[xbx*8] = [xsi].e[xbx*8] / (d6 + d7)
            mov xax, mj1
            fSlv8 [xsi].d[xax*8] = ([xsi].e[xbx*8] * (d6 + d7))
            fSlv8 d8 = [xsi].d[xax*8];
            fSlv8 d9 = d5 - [xsi].d[xbx*8]
            mov xax, j
            add xax, 2
            ForLpD i2, xax, n0
                fSlvW [xsi].d[xax*8] -= d9
            Next i2
            fSlvW d1 += d9
            mov xax, k
            fSlv8 d6 = [xsi].d[xax*8];
            fSlv8 d10 = 1.0
            fSlv8 d11 = d10
            fSlv8 d12 = d10
            mov xax, mj1
            fSlv8 d13 = [xsi].e[xax*8]
            fSlv8 d14 = 0.0
            fSlv8 d15 = 0.0
            mov xax, k
            dec xax
            ForLpN i3, xax, j
                fSlv8 d12 = d11
                fSlv8 d11 = d10
                fSlv8 d15 = d14
                fSlv8 d5 = d10 * [xsi].e[xax*8]
                fSlv8 d9 = d10 * d6;
                fSlv8 d7 = (d6^2+ [xsi].e[xax*8]^2)^0.5
                mov xcx, i3
                add xcx, 1
                fSlv8 [xsi].e[xcx*8] = (d14 * d7);
                fSlv8 d14 = [xsi].e[xax*8] / d7;
                fSlv8 d10 = d6 / d7;
                fSlv8 d6 = d10 * [xsi].d[xax*8] - d14 * d5;
                fSlv8 [xsi].d[xcx*8] = d9 + d14 * (d10 * d5 + d14 * [xsi].d[xax*8])
                ForLpD i4, 0, n0
                    matrix i4, i3, n0
                    push xax
                    add xax, 1
                    pop xcx
                    fSlv8 d9 = [xsi].V[xax*8]
                    fSlv8 [xsi].V[xax*8] = d14 * [xsi].V[xcx*8] + d10 * d9
                    fSlv8 [xsi].V[xcx*8] = d10 * [xsi].V[xcx*8] - d14 * d9
                Next i4
            NextN i3
            fSlv8 d6 = -d14 * d15 * d12 * d13 * [xsi].e[xbx*8] / d8
            fSlv8 [xsi].e[xbx*8] = (d14 * d6)
            fSlv8 [xsi].d[xbx*8] = (d10 * d6)
           
            fSlv8 r8temp1 = abs([xsi].e[xbx*8])
            fSlv8 r8temp2 = abs(d3 * d2)
        @whilethis r8temp1 fGT r8temp2

It just means 3 bytes more than the .repeat ... .until example

 :biggrin: I have to make @repeat/@until, just I don't needed yet. 

Equations in Assembly: SmplMath