I've got some code that gcc
(4.8.5, if it matters) compiles into nearly identical binary on two different machines except for one spot, where something in the toolchain on one machine decides to use a "near" JE instruction while the toolchain on the other machine decides to use a "short" JE instruction:
41e274: 85 ed test %ebp,%ebp 41e274: 85 ed test %ebp,%ebp
41e276: 0f 84 14 00 00 00 je 41e290 | 41e276: 74 18 je 41e290
41e27c: 31 ed xor %ebp,%ebp | 41e278: 31 ed xor %ebp,%ebp
41e27e: 48 81 c4 30 01 00 00 add $0x130,%rsp | 41e27a: 48 81 c4 30 01 00 00 add $0x130,%rsp
41e285: 89 e8 mov %ebp,%eax | 41e281: 89 e8 mov %ebp,%eax
41e287: 5b pop %rbx | 41e283: 5b pop %rbx
41e288: 5d pop %rbp | 41e284: 5d pop %rbp
41e289: 41 5c pop %r12 | 41e285: 41 5c pop %r12
41e28b: c3 retq | 41e287: c3 retq
41e28c: 0f 1f 40 00 nopl 0x0(%rax) | 41e288: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,
> 41e28f: 00
41e290: 48 8d 7c 24 60 lea 0x60(%rsp),%rdi 41e290: 48 8d 7c 24 60 lea 0x60(%rsp),%rdi
I'm assuming this is some sort of optimization (though I'm unclear as to whether it's the compiler or assembler that is being clever).
The odd thing, though, is that (in the same object file) there are other "nearby je
branches" (to less than 40 or so bytes away) that are not similarly optimized to the single byte opcode:
c320: 45 85 ed test %r13d,%r13d c320: 45 85 ed test %r13d,%r13d
c323: 0f 84 17 00 00 00 je c340 c323: 0f 84 17 00 00 00 je c340
c329: 45 31 ed xor %r13d,%r13d c329: 45 31 ed xor %r13d,%r13d
c32c: 48 81 c4 30 01 00 00 add $0x130,%rsp c32c: 48 81 c4 30 01 00 00 add $0x130,%rsp
c333: 44 89 e8 mov %r13d,%eax c333: 44 89 e8 mov %r13d,%eax
c336: 5b pop %rbx c336: 5b pop %rbx
c337: 5d pop %rbp c337: 5d pop %rbp
c338: 41 5c pop %r12 c338: 41 5c pop %r12
c33a: 41 5d pop %r13 c33a: 41 5d pop %r13
c33c: 41 5e pop %r14 c33c: 41 5e pop %r14
c33e: c3 retq c33e: c3 retq
c33f: 90 nop c33f: 90 nop
c340: 4c 8d 74 24 60 lea 0x60(%rsp),%r14 c340: 4c 8d 74 24 60 lea 0x60(%rsp),%r14
Is there some parameter/configuration for gcc
(or ld
) that I can use to control this? I'd like to ensure that my code results in the same binary when compiled elsewhere.