0
.pos 0 code
    jmp _start

.pos 0x100 code
_start:
    xorq %rcx, %rcx
    irmovq $3, %rax
    irmovq $1, %rsi
    jmp loop
loop:
    addq %rsi, %rcx
    pushq %rcx
    subq %rax, %rcx
    popq %rcx
    jle loop
    ret

I am trying to write the equivalent of a for loop in y86 but for some odd reason its only iterating once. Note that y86 doesnt have the cmp instruction so i use push, sub and pop.

Alexa Jenasoba
  • 93
  • 1
  • 1
  • 6
  • One idiomatic way to loop in x86 is `dec reg` / `jnz top_of_loop` to count down a counter from n to 1 (falling out of the loop when it reaches 0). [Why are loops always compiled into "do...while" style (tail jump)?](https://stackoverflow.com/q/47783926) You can do that in y86 with `subq` / `jne` aka `jnz`. If you also need an integer counting upwards for use in the loop body, you can do that separately in another register with an `add`. If you have a spare register, that's simpler that push/sub/pop to emulate cmp. – Peter Cordes Oct 29 '20 at 22:51
  • while those theoretical approaches may be good and all, im merely curious why the current code is only iterating once? rax is 3 and i compare rcx to rax. – Alexa Jenasoba Oct 29 '20 at 22:56
  • `3 <= 1` is false on the first iteration so jle falls through. y86 uses AT&T-style syntax that makes the semantic meaning of comparisons like `jle` opposite from the order of operands for sub / cmp. – Peter Cordes Oct 29 '20 at 23:01
  • isn't `cmp %rcx, %rax` the same as: `push %rax sub %rcx, %rax pop %rax` – Alexa Jenasoba Oct 29 '20 at 23:15
  • Yes, it is. So with RAX=3 and RCX=1, cmp / jle is taken if `3 <= 1`. Which it isn't, so you fall out of your `do{}while(rcx <= rax)` loop. – Peter Cordes Oct 30 '20 at 01:16
  • but even if in the order is switched, there is still only one iteration so am i not implementing compare right? – Alexa Jenasoba Oct 30 '20 at 01:36
  • Do you have a y86 debugger that lets you single-step through your code and look at register values? When you switched the order, did you also change to saving/restoring `%rcx` instead of `%rax`, because that's the one getting destroyed? – Peter Cordes Oct 30 '20 at 01:39
  • `push %rcx sub %rax, %rcx pop %rcx` although this seems wrong to sub 1 - 3... – Alexa Jenasoba Oct 30 '20 at 04:03
  • But post your answer as an answer, not an edit that turns it into a non-question! Now your code doesn't match the text, which claims it only iterates once. That is correct code, though. (You could optimize to avoid push/pop by doing `mov %rcx, %rdx` / `sub %rax, %rdx` to just compute in a scratch register instead of saving/restoring RCX. You have lots of unused registers. Also `jmp loop` is totally useless; execution falls into the loop on its own.) – Peter Cordes Oct 31 '20 at 01:50

0 Answers0