Your main mistake is to use tags, but I’m missing it.
When it’s hard to figure out why a program is running, debuggers come to the rescue (step-by-step program execution)
so here we go on step by step:
after reading a = 0, the code is executed
if a = 0 then write ('Banned 0! Input a again? (y / n)');
read (p);
if the condition is fulfilled, you only have WRITE executed, the reading of r will be performed anyway, these two lines need to be taken in the BEGIN ... END operator brackets ....
if a = 0 then begin write ('Banned 0! Input a again? (y / n)'); read (p); end; go further when it comes to terms
if p = 'y' then goto first;
the first time it is not executed, so the code goes to the conditions
if (p <> 'y') and (p <> 'n') then goto second;
and here already, P has an incomprehensible value of why it is executed, and if the code is executed again from First to checks or from Second to checks, they are performed again and again, therefore the value of P does not change - that’s what a kind of looping turns out to be.
Output: When executing the code after the label, change the value of P to what neutral
Real output: use a loop with a post condition.
Here is the code without this repetition:
program corekey; label first,second,third; var a,x,b:real; p:char; begin write('ax+b=0 '); first: p:='n'; writeln('write a '); readln(a); second : if a=0 then begin write('Banned 0! Input a again?(y/n) '); read(p); end; if p='y' then goto first; if (p<>'y')and(p<>'n') then goto second; write('write b '); read(b); x:=-b/a; write(x); third: writeln ('Begining again? (y/n) '); readln(p); if p='y' then goto first; if p='n' then write('Press Enter!'); if(p<>'y') and (p<>'n') then goto third; read; end.