0
     int Perm[4326];

      
        __asm
{                   MOV EBX, 6
        FACT:       MOV Perm[4320 + EBX * 4], EBX     
                    DEC EBX
                    TEST EBX, EBX
                    JE FACTEND
                    JMP FACT
        FACTEND:     // This puts the numbers 1,2,3,4,5,6 in Perm[4320]...Perm[4325]
                    //In between there are is some recursion that's not relevant
                    MOV EBX, 2
                    XOR ESI,ESI
                    MOV EAX, Perm[EBX*4+4319]
                    TEST AL,1
                    JZ EVEN             
                    MOV ECX, Perm[4320]
                    MOV Perm[4320], EAX
                    MOV Perm[EBX * 4 + 4319], ECX
                    JMP KLOOP
       EVEN:        MOV ECX, Perm[ESI * 4 + 4320]
                    MOV Perm[ESI*4 + 4320], EAX             
                    MOV Perm[EBX * 4 + 4319], ECX
       KLOOP:       INC ESI

The memory looks like this from Perm[4321] to Perm [4325] :

01000000 02000000 03000000 04000000 05000000 06000000

What I'm struggling with is that

MOV EAX, Perm[EBX*4+4319] Results in EAX being 00000002

While MOV ECX Perm[4320*4] Results in ECX being 01000000

And the after the swap (EVEN label) the memory becomes

00000002 00000000 03010000 04000000 05000000 06000000

I am trying to implement in assembly the Heap algorithm for permutations of an array, in this case an array of int.

With this being little endian it doesn't make sense that 1 would be written as 01000000 in the memory since it should be 00 00 00 01 , I also don't understand why I'm getting 2 different results with seemingly the same instruction (MOV EAX, Perm and MOV ECX, Perm)

JustJohn
  • 59
  • 1
  • 7
  • 2
    Not sure if it applies to VC++ inline asm, but usually the offsets in assembly language are in bytes. Are you sure that `mov Perm[4320], ecx` is really loading from element 4320 of the array, not element 1080? – Nate Eldredge Jun 13 '21 at 14:26
  • 1
    How are you looking at memory in your tests, as little-endian integers or as bytes? That could account for a discrepancy between `02 00 00 00` and `00000002`. – Nate Eldredge Jun 13 '21 at 14:29
  • @NateEldredge it appears that I had to add *4 to every instance (for example [EBX*4 + 3319]) – JustJohn Jun 13 '21 at 15:16
  • 1
    [EBX*4 + 3319*4] , typo – JustJohn Jun 13 '21 at 15:28
  • @NateEldredge: MSVC inline asm is "normal" like MASM. C var names in addressing modes get replaced with `EBP + constant` instead of an absolute address, but other constants aren't magically scaled. (Often inline asm code gets a pointer into a register, but it probably works fine to use `perm[reg*4 + const]` to eventually get an addressing mode like `[ebp - perm_offset + reg*4 + const]`, but wouldn't hurt to check that on Godbolt or in a debugger.) – Peter Cordes Jun 13 '21 at 15:52

0 Answers0