views:

234

answers:

4

Hi everyone,

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)
    }
}
+2  A: 

For that you would probably use the loop instruction that decrements the ecx (often called, extended counter) at each loop and goes out when ecx reaches zero.But why use inline asm for it anyway? I'm pretty sure something as simple as that will be optimized correctly by the compiler...

(We say x86 architecture, because it's based on 80x86 computers, but it's an "ok" mistake =p)

Melanikus
Jejej thanks... I build software for a few years.. but now is when I'm starting to self study about PC Architecture, Assembler and more.
Sheldon
+5  A: 

Use gcc to generate the assembly code

gcc -S -c sample.c

man gcc is your friend

alinrus
Or: Man, gcc is your friend! LOL, a compiler that generates assembly language. Who would have thought it.
binarycoder
Haha, gcc's manpage might possibly be useful, but note that gcc's manpage is 12,838 lines! The "-S" option doesn't even show up until the 678th line!
rascher
@rascher having to read? Perish the thought! Regex-compatible searching? Heresy! ;)
mrduclaw
+6  A: 

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.

Artelius
Thanks, so I can use the registries... decrement and jumps... umm now I have a shape
Sheldon
+7  A: 

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) { }

asveikau
Simply Beautiful. :)
mrduclaw
I agree... asveikau: That's a very nice explanation, now I now where to begin. Thank you very very much.
Sheldon