첫번째 명령 push bp
이므로 스택의 꼭대기 값이 지금부터 bp
값이다.
sp
(스택 맨 위로 포인터) 조작을 포함하여 더 많은 작업을 수행하지만 ret
직전에 이전 bp
값을 가리 킵니다.
ret
은 스택에서 값을 가져오고 ip
(명령 포인터)을 해당 값으로 설정합니다. 정상적인 상황에서는 스택의 맨 위에 실행할 다음 명령어의 주소가 있어야합니다 (대개 call
명령어를 넣고 카운터 동작이 ret
이고 스택에 call
다음 명령어의 주소를 넣은 다음 ip
을 설정합니다) 인수 값을 call
명령으로부터).
하지만 당신의 코드 ip
을에
는 CPU가 다음 코드로 데이터 바이트를 실행하려고합니다, 그래서 가능성이 높다 포인트 어딘가에 스택 메모리 (또는 "악화")로 이전
bp
값으로 설정하고, 행동은 예상치 못한입니다 (OS로 돌아가는 것은 실제로 꽤 좋은 최종 결과 일 것이고, 그러한 실수는 대개 응용 프로그램의 충돌이나 데이터의 손실로 끝납니다).
pop bp
을 ret
앞에 추가하십시오 (에 의해 sp
값을 복원 한 후). 당신이 call/ret
에 의해 스택, 명시 적으로 push/pop
또는 add/sub sp
, 또는 암시 적으로 조작 할 때마다
, 당신은 더 스택을 사용하기 전에 모든 코드 경로에 올바른 sp
값으로 종료해야합니다. 예. 일반적으로 모든 push
에는 pop
의 페어링이 필요하고 모든 call
은 ret
으로 반환해야합니다. 그런 규칙을 위반하고 스택을 다른 방법으로 올바른 상태로 조정할 수있는 충분한 경험이없는 경우가 아니면 실제로 당신의 진입 지점에서 스택에서 반송 주소가 있는지
BTW, 그것이 의문이다 (당신이 call
이를 -ing 다른 코드를 가지고, 또는 경우이며, 귀하의 질문에서 명확하지 않다 귀하의 프로그램의 진입 점).
DOS 실행 파일과 비슷하고 엔트리 포인트 일 경우 int 21h, 4Ch
OS 서비스 호출로 프로그램을 종료해야합니다.
어떤 어셈블러를 사용하고 있습니까? 또한 질문은 의미가 없습니다. * 프로그램을 실행할 때 * 어셈블러 *가 무언가를합니까? 문제가 발생하면 어셈블러가 실행되지 않습니다.코드를 어셈블 할 때 또는 바이너리를 실행할 때이 메시지가 표시됩니까? 이것이 실제로 오류라고 확신합니까? –
귀하의 질문은 무엇입니까? – fuz
** 'call twoMash' 이후에 ** 코드는 무엇입니까? 게시하지 않았지만 아마 프로그램을 끝낼 것입니다 (예 :'mov ax, 4c00h','int 21h'). –