缓冲区溢出简单例子有不懂的地方

void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
int *ret;

ret = buffer1 + 12;
(*ret) += 8;
}

void main() {
int x;

x = 0;
function(1,2,3);
x = 1;
printf("%d\n",x);
}

这段程序实现输出结果是x=0.有两句话我不是太懂,function里面,
ret = buffer1 + 12;
(*ret) += 8
12和8是怎么来的?
我知道buffer1+12之后是指向function执行完之后的返回地址, (*ret) += 8是跳过x=1这句指令。现在问题是怎么知道加12就是指向了堆的ret。不同系统都是加12吗?还是每个系统是不一样的。还有8是不是通过看汇编码看出来?

ret 操作的内存是什么?这个好像是随机的,所以出错是正常的。不出错,是运气。

这个偏移量是根据函数调用的栈帧的内存布局来的。
地址由高到低。ret返回地址。函数参数。函数内局部变量。