Here's a simple C++ program:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> a = {7};
int b = 7;
if (a[0] > 6) {
cout << "a bigger than 6" << endl;
}
if (b > 6) {
cout << "b bigger than 6" << endl;
}
return 0;
}
Upon compiling with gdb -g ...
and generating assembly with objdump --source-comment=";SOURCE: " -wlCS ...
, here's the conditionals' x86
assembly code:
;SOURCE: if (a[0] > 6) {
1321: 48 8d 45 b0 lea -0x50(%rbp),%rax
1325: be 00 00 00 00 mov $0x0,%esi
132a: 48 89 c7 mov %rax,%rdi
132d: e8 82 02 00 00 call 15b4 <std::vector<int, std::allocator<int> >::operator[](unsigned long)>
1332: 8b 00 mov (%rax),%eax
1334: 83 f8 06 cmp $0x6,%eax
1337: 0f 9f c0 setg %al
133a: 84 c0 test %al,%al
133c: 74 2b je 1369 <main+0xc0>
and
;SOURCE: if (b > 6) {
1369: 83 7d ac 06 cmpl $0x6,-0x54(%rbp)
136d: 7e 2b jle 139a <main+0xf1>
In the second example, the value of b
is simply compared with 6
and the jump statement skips ahead if b
<= 6
.
In the first example, after the value 7
is read from the vector a
, it is stored in %eax
and compared with 6
. I see that setg
will set %al
to match the "greater" condition (ZF
=0
and SF
=OF
), test
will set the zero flag to the inverse of %al
(in this case), and je
will jump if the zero flag is set (indicating that a[0]
was not greater than 6
).
My question is why setg
, test
, and je
are needed here. Couldn't the latter portion of the first example be implemented in the same way as the second one, using only cmp(l)
and jle
? Would this potentially be faster?
Note: this doesn't have anything to do with objdump
; the output of gdb -S
contains the same instructions.
g++ (Ubuntu 11.3.0-1ubuntu1\~22.04.1) 11.3.0
GNU objdump (GNU Binutils for Ubuntu) 2.38