2017-01-04 5 views
-3

나는 어셈블러는 말한다 내 프로그램을 실행하면 : 그것은 RET에 도달하면프로그램은 총회의 운영 체제로 제어를 반환했습니다 8086

프로그램이 운영 체제

제어를 반환했습니다 교수.

twoMash PROC 
    push bp 
    mov bp, sp 
    sub sp, 2 

    NOT ax 
    ADD ax,1 

    mov sp,bp 
    ret 
twoMash ENDP 
main

이런 식으로 정의된다 : 코드 같다

main: 
    mov ax,100b 
    push ax 
    call twoMash 
+0

어떤 어셈블러를 사용하고 있습니까? 또한 질문은 의미가 없습니다. * 프로그램을 실행할 때 * 어셈블러 *가 무언가를합니까? 문제가 발생하면 어셈블러가 실행되지 않습니다.코드를 어셈블 할 때 또는 바이너리를 실행할 때이 메시지가 표시됩니까? 이것이 실제로 오류라고 확신합니까? –

+1

귀하의 질문은 무엇입니까? – fuz

+0

** 'call twoMash' 이후에 ** 코드는 무엇입니까? 게시하지 않았지만 아마 프로그램을 끝낼 것입니다 (예 :'mov ax, 4c00h','int 21h'). –

답변

2

첫번째 명령 push bp이므로 스택의 꼭대기 값이 지금부터 bp 값이다.

sp (스택 맨 위로 포인터) 조작을 포함하여 더 많은 작업을 수행하지만 ret 직전에 이전 bp 값을 가리 킵니다.

ret은 스택에서 값을 가져오고 ip (명령 포인터)을 해당 값으로 설정합니다. 정상적인 상황에서는 스택의 맨 위에 실행할 다음 명령어의 주소가 있어야합니다 (대개 call 명령어를 넣고 카운터 동작이 ret이고 스택에 call 다음 명령어의 주소를 넣은 다음 ip을 설정합니다) 인수 값을 call 명령으로부터).

하지만 당신의 코드 ip을에

는 CPU가 다음 코드로 데이터 바이트를 실행하려고합니다, 그래서 가능성이 높다 포인트 어딘가에 스택 메모리 (또는 "악화")로 이전 bp 값으로 설정하고, 행동은 예상치 못한입니다 (OS로 돌아가는 것은 실제로 꽤 좋은 최종 결과 일 것이고, 그러한 실수는 대개 응용 프로그램의 충돌이나 데이터의 손실로 끝납니다).

pop bpret 앞에 추가하십시오 (에 의해 sp 값을 복원 한 후). 당신이 call/ret에 의해 스택, 명시 적으로 push/pop 또는 add/sub sp, 또는 암시 적으로 조작 할 때마다

, 당신은 더 스택을 사용하기 전에 모든 코드 경로에 올바른 sp 값으로 종료해야합니다. 예. 일반적으로 모든 push에는 pop의 페어링이 필요하고 모든 callret으로 반환해야합니다. 그런 규칙을 위반하고 스택을 다른 방법으로 올바른 상태로 조정할 수있는 충분한 경험이없는 경우가 아니면 실제로 당신의 진입 지점에서 스택에서 반송 주소가 있는지


BTW, 그것이 의문이다 (당신이 call이를 -ing 다른 코드를 가지고, 또는 경우이며, 귀하의 질문에서 명확하지 않다 귀하의 프로그램의 진입 점).

DOS 실행 파일과 비슷하고 엔트리 포인트 일 경우 int 21h, 4Ch OS 서비스 호출로 프로그램을 종료해야합니다.