A base pointer is a processor register that gives a function a stable reference point for stack-resident data. In the fgoto setup, the function saves %rbp, copies %rsp into %rbp, and reserves 48 bytes; local objects are then addressed with negative offsets such as -36(%rbp). section 13.5
The stack-frame pattern connects the base pointer to these operations:
- Save the caller's base-pointer value before using the register for the current function. section 13.5
- Copy the stack pointer into the base pointer to establish the current frame's reference point. section 13.5
- Access automatic variables and compound literals through fixed offsets relative to that point. section 13.5
Listing 13.4 An assembler version of the fgoto function
.type fgoto, @function
fgoto:
pushq %rbp # Save base pointer
movq %rsp, %rbp # Load stack pointer
subq $48, %rsp # Adjust stack pointer
movl %edi, -36(%rbp) # fgoto#0 => n
movl $0, -4(%rbp) # init j
movq $0, -16(%rbp) # init p
.L_AGAIN:
cmpq $0, -16(%rbp) # if (p)
je .L_ELSE
movq -16(%rbp), %rax # p ==> rax
movl (%rax), %edx # *p ==> edx
movq -24(%rbp), %rax # ( == q)?
cmpq -16(%rbp), %rax # (p == )?
jne .L_YES
movl $.L_STR_EQ, %eax # Yes
jmp .L_NO
.L_YES:
movl $.L_STR_NE, %eax # No
.L_NO:
movl -4(%rbp), %esi # j ==> printf#1
movl %edx, %ecx # *p ==> printf#3
movq %rax, %rdx # eq/ne ==> printf#2
movl $.L_STR_FRMT, %edi # frmt ==> printf#0
movl $0, %eax # clear eax
call printf
.L_ELSE:
movq -16(%rbp), %rax # p ==|
movq %rax, -24(%rbp) # ==> q
movl -4(%rbp), %eax # j ==|
movl %eax, -28(%rbp) # ==> cmp_lit
leaq -28(%rbp), %rax # &cmp_lit ==|
movq %rax, -16(%rbp) # ==> p
addl $1, -4(%rbp) # ++j
movl -4(%rbp), %eax # if (j
cmpl -36(%rbp), %eax # <= n)
jbe .L_AGAIN # goto AGAIN
leave # Rearange stack
ret # return statement
Trace the prologue and the offset-based accesses in the assembler listing for fgoto. section 13.5

