Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Translate a FOR to assembler

Tags:

c

x86

assembly

I need to translate what is commented within the method, to assembler. I have a roughly idea, but can't.

Anyone can help me please? Is for an Intel x32 architecture:

int 
secuencia ( int n, EXPRESION * * o )
{
  int a, i;
//--- Translate from here ...
  for ( i = 0; i < n; i++ ){
    a = evaluarExpresion( *o );
    o++;
  }
  return a ;
//--- ... until here.
}

Translated code must be within __asm as:

__asm {
        translated code
}

Thank you,

FINAL UPDATE:

This is the final version, working and commented, thanks to all for your help :)

int
secuencia ( int n, EXPRESION * * o )
{
    int a = 0, i;
    __asm
    {
        mov dword ptr [i],0             ; int i = 0
        jmp salto1
        ciclo1:
        mov eax,dword ptr [i]           
        add eax,1                       ; increment in 1 the value of i
        mov dword ptr [i],eax           ; i++
        salto1: 
        mov eax,dword ptr [i]           
        cmp eax,dword ptr [n]           ; Compare i and n
        jge final                       ; If is greater goes to 'final'
        mov eax,dword ptr [o] 
        mov ecx,dword ptr [eax]         ; Recover * o (its value)
        push ecx                        ; Make push of * o (At the stack, its value)
        call evaluarExpresion           ; call evaluarExpresion( * o )
        add esp,4                       ; Recover memory from the stack (4KB corresponding to the * o pointer)
        mov dword ptr [a],eax           ; Save the result of evaluarExpresion as the value of a
        mov eax,dword ptr [o]           ; extract the pointer to o
        add eax,4                       ; increment the pointer by a factor of 4 (next of the actual pointed by *o)
        mov dword ptr [o],eax           ; o++
        jmp ciclo1                      ; repeat
        final:                          ; for's final
        mov eax,dword ptr [a]           ; return a - it save the return value at the eax registry (by convention this is where the result must be stored)
    }
}
like image 552
Sheldon Avatar asked Mar 16 '26 12:03

Sheldon


2 Answers

Essentially in assembly languages, strictly speaking there isn't a notion of a loop the same way there would be in a higher level language. It's all implemented with jumps (eg. as a "goto"...)

That said, x86 has some instructions with the assumption that you'll be writing "loops", implicitly using the register ECX as a loop counter.

Some examples:

    mov ecx, 5         ; ecx = 5
.label:
    ; Loop body code goes here
    ; ECX will start out as 5, then 4, then 3, then 1...
    loop .label        ; if (--ecx) goto .label;

Or:

    jecxz .loop_end    ; if (!ecx) goto .loop_end;
.loop_start:
    ; Loop body goes here
    loop .loop_start   ; if (--ecx) goto .loop_start;
.loop_end:

And, if you don't like this loop instruction thing counting backwards... You can write something like:

    xor ecx, ecx       ; ecx = 0
.loop_start:
    cmp ecx, 5         ; do (ecx-5) discarding result, then set FLAGS
    jz .loop_end       ; if (ecx-5) was zero (eg. ecx == 5), jump to .loop_end
    ; Loop body goes here.
    inc ecx            ; ecx++
    jmp .loop_start
.loop_end:

This would be closer to the typical for (int i=0; i<5; ++i) { }

like image 136
asveikau Avatar answered Mar 19 '26 03:03

asveikau


Note that

for (init; cond; advance) {
    ...
}

is essentially syntactic sugar for

init;
while(cond) {
   ...
   advance;
}

which should be easy enough to translate into assembly language if you've been paying any attention in class.

like image 27
Artelius Avatar answered Mar 19 '26 01:03

Artelius



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!