В некотором полу-ассемблере, предполагая что-то вроде x86. (BP является псевдокодом для EBP или RBP, при условии, что вы на самом деле не компилируете для 16-битного режима. Вероятно, 32-битный режим так, что int
имеет ту же ширину, что и адрес возврата.)
; entrance:
; - stack has return address to main
push bp ; decrement SP by a pointer width
mov bp,sp
sub sp, 10*sizeof(int) ; reserve space for an array
;....
; doNotTouch[0] is probably at [bp - 10*sizeof(int)]
Когда вы переходите к 14, вы сначала перезаписываете сохраненный bp при i == 10, а затем адрес возврата в main (что правильно), а затем перезаписываете еще немного, что в конечном итоге вызывает ошибку сегмента. Так что вам нужно всего лишь сделать *(doNotTouch + 11) = (int) &secret;
- при условии, что int - это размер указателя на функцию. (Или немного больше, если компилятор оставил пробел для выравнивания стека или для собственного использования. В отладочной сборке другие локальные блоки будут иметь слоты стека. Их перезапись может привести к бесконечному циклу, выходящему за пределы.)
Затем следует ваш printf, а затем функция возвращается, но она не возвращается к основному, а «переходит» к secret
.
Когда возвращается secret
, это фактически теперь возврат из основного, но этоне может сделать return 0;
Так что секрет должен быть:
int secret()
{
printf("now inside secret()!\n");
return 0;
}
Отказ от ответственности: ".... Я думаю."