I saw this looking into something else, and have been trying to figure it out. I’ll be the first to admit that i don’t understand every trick and incantation of assembly. Indeed my assembly skills are quite poor.
Given the following zig program
export fn square(num: i32) i32 {
return num * num;
}
You will get the following assembly output:
square:
push rbp
mov rbp, rsp
sub rsp, 288
mov dword ptr [rbp - 284], edi
lea rax, [rbp - 280]
mov qword ptr [rbp - 16], rax
mov qword ptr [rbp - 8], 32
mov qword ptr [rbp - 24], 0
imul edi, edi
mov dword ptr [rbp - 288], edi
seto al
jo .LBB0_1
jmp .LBB0_2
.LBB0_1:
lea rdi, [rbp - 24]
call "debug.FullPanic((function 'panic')).integerOverflow"
.LBB0_2:
mov eax, dword ptr [rbp - 288]
add rsp, 288
pop rbp
ret
(Note, that this is the default function used in godbolt when you open a zig file)
My question is why does the compiler issue a seto al
instruction. I know that seto checks for the overflow bit in the eflags
register, but al
is never used. jo
jumps based off of the eflags
register, and after that eax
is overwritten with the result of the multiplication.