2

I'm going though 'Computer Systems: A Programmer's Perspective', chapter 3 which is about machine-level representation. I'm currently on 'Arithmetic and Logic Operations', doing one of the practice problem. The problem gives C code fragment:

short scale3(short x, short y, short z){
    short t = ----------------;
    return t;
}

additionally i'm given an assembly code, generated from the COMPLETE code in scale3 function:

scale3:
    leaq (%rsi, %rsi, 9), %rbx
    leaq (%rbx, %rdx), %rbx
    leaq (%rbx, %rdi, %rsi), %rbx
    ret

From the generated assembly code i'm supposed to full-fill missing part in the C source code. According to X86-64 convention, i followed the rules of memory referencing and easily fond that, t(in the C code) should be assigned to -> t = 10 * y + z + y * x;. I checked the answer and it matches. Out of curiosity, i tested the code and the code generated from the function didn't match the given assembly code.

I'm working on 64-bit Linux machine, and my GCC generated the following code:

scale3:
    leal  10(%rdi), %eax
    imull %eax, %esi
    leal  (%rsi,%rdx), %eax
    ret

Can anybody explain to my why i get different representations? This is probably 15th+ generate code and i've never got different result compared to the book.

  • 1
    Are you sure you gave us the right code. `leaq (%rsi, %rsi, 9), %rbx` isn't a valid instruction because the last parameter can't be 9 (it is the scaling factor which can only be 1,2,4,8), not `9`. In AT&T syntax memory operands are segment:displacement(base, index, scale)` . The calculation is displacement+(base + (index * scale)). `segment` is optional. If scale is omitted then it is the same as `1`. If `Index` and `scale` are omitted then index*scale is considered 0). If dispalcement is omitted it is the same as 0. – Michael Petch Sep 03 '19 at 14:58
  • Hm...you are absolutely correct! There should be 1,2,4 or 8. The book stated like that as well. I rechecked it, and it's correct. In the answer, it's given as 9. – abstraction_builder Sep 03 '19 at 16:25
  • 2
    @MichaelPetch Also, `leaq (%rbx, %rdi, %rsi), %rbx` does not exist at all, since `scale` is always immediate. I'd recommend throwing the book away. – EOF Sep 03 '19 at 18:28
  • You're right, it should not be a register. I guess they messed up there. But overall, this book is one of the best i'v ever read. It's used in many, many universities at machine organization class, including stanford and cmu itself. I'll probably keep reading it. Thanks for your time! – abstraction_builder Sep 03 '19 at 18:39
  • @EOF : True, I stopped looking at the code after the first instruction that can't be encoded and threw up my hands and said to myself the answer to this question is that there is no answer beyond the book being foobared lol. – Michael Petch Sep 03 '19 at 20:01
  • This generated assembly is total BS. – S.S. Anne Sep 18 '19 at 19:09
  • 2
    CS:APP global edition's examples are full of broken nonsense, errors introduced by people other than the authors. [Is there a scaled-by-register operand form in x86 (used as an operand for leaq)?](https://stackoverflow.com/q/62668573) This is not real GCC output, but the clowns that made up the broken examples claim it is. – Peter Cordes Jul 01 '20 at 02:15
  • Yes, indeed. I found that out that the hard way – abstraction_builder Jul 02 '20 at 07:01

0 Answers0