0

I am miserably confused right now when trying to discern assembly language. I am asked to convert the following x86-84 code to Y86-84:

long arith(long int x, long int y, long int z) {

return (x+y+z) & (x+4+48*y);

}

In x86-64:

arith:
leaq (%rsi, %rsi, 2), %rax
salq $4, %rax
leaq 4(%rdi, %rax), %rax
addq %rdi, %rsi
addq %rdx, %rsi
andq %rsi, %rax
ret

Before I convert, I'm having a hard time understanding what's even going on in x86-64. I would be immensely appreciative to anyone who could walk me through what is even going on in this code.

  • 1
    Which part is confusing? Show what you figured out and where you got stuck. See also [What's the purpose of the LEA instruction?](https://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction) and remember that left shift is multiplying by powers of two. First insn gives `3*y`, next `16*3*y`, next the right bracket, next two the left bracket finally the `&`. – Jester Nov 02 '17 at 02:28
  • The first two lines were confusing me, but I walked through it more carefully and remembering that the left shift multiplies by powers of two helped a lot. So as I see it now, the first two lines consists of putting 48y into register %rax, the next line consists of placing 48y added by x+4 into %rax, the next 2 lines consist of having the %rsi register contain x+y+z, and the last line does the final & operation of the registers that now have the two desired values. – AnonymousCPU Nov 02 '17 at 02:38
  • With that in mind though, what is important to keep in mind converting to Y86? I was told there is no leaq instruction in y86, so where should I start in trying to convert? – AnonymousCPU Nov 02 '17 at 02:39
  • 1
    Turn them into additions, aren't you overthinking this? – Jester Nov 02 '17 at 02:41
  • @Jester : seems like a logical progression of your previous answer dealing with 32-bit. https://stackoverflow.com/questions/13545606/ia32-assembly-code-to-y86-assembly-code-leal-instruction – Michael Petch Nov 02 '17 at 02:44
  • So to get 48y, I would need to turn leaq into a ton of additions? There's no efficient way of getting 48y into %rax? – AnonymousCPU Nov 02 '17 at 03:07

2 Answers2

0

Here's my first shot: In Y86:

arith:
addq %rsi, %rsi
addq %rsi, %rsi
addq %rsi, %rsi
addq %rsi, %rsi
addq %rsi, %rax
addq %rsi, %rsi
addq %rsi, %rax
addq %rdi, %rax
addq 4, %rax
addq %rdi, %rsi
addq %rdx, %rsi
addq %rsi, %rax
ret

I believe the line 'addq 4, %rax' is incorrect. How should I add 4 to the value stored in the %rax register?

EDIT: I see a bigger issue in that after adding to %rsi I can't seamlessly get x+y+z into %rsi as I did with x86. How can I get x+y+z stored into a register then?

  • x86 AT&T syntax would use `add $4`, %rax`, but y86 uses separate mnemonics for loads vs. mov-immediate, doesn't it? So IDK if it needs to decorate immediates with `$` to distinguish them from memory operands. But it might require them anyway for consistency. – Peter Cordes Nov 02 '17 at 03:23
  • The more obvious bug is that you add to `%rax` without moving anything to it first. On function entry, it holds garbage. x86 LEA's destination is write-only. See https://stackoverflow.com/questions/13545606/ia32-assembly-code-to-y86-assembly-code-leal-instruction. I'd suggest `irmov $1, %rax` before the first `add` to RAX, instead of copying a register there. That saves an instruction vs. copy and then add-immediate. (I forget if y86 saves code bytes from `irmov $1, %eax` the way x86 does, with implicit zero extension into rax instead of a longer instruction) – Peter Cordes Nov 02 '17 at 03:24
  • I'm very confused by the irmovq, rmmovq, and mrmovq instructions. What exactly do they accomplish? – AnonymousCPU Nov 02 '17 at 03:37
  • irmov loads a constant into a register. rmmov stores a register to a memory location. mrmov loads a value from memory into a register. – prl Nov 02 '17 at 04:27
-1

Here's my second shot:

arith:
subq %r8, %r8
addq %rdi, %r8
addq %rsi, %r8
addq %rdx, %r8
addq %rsi, %rsi
addq %rsi, %rsi
addq %rsi, %rsi
addq %rsi, %rsi
subq %rax, %rax
addq %rsi, %rax
addq %rdi, %rax
addq $4, %rax
andq %r8, %rax