2017-11-03 14 views
0

안녕하세요 저는 두 개의 숫자가 emu8086의 화면에서 입력 된 절차를 만들고 싶습니다. 절차가 완료된 후에도 계속 프로그램을 좋아합니다. 나는 프로 시저 sumUp을 호출하고 절차를 완료 한 후 프로그램을 완료하면 좋은 결과를 얻습니다. 난 당신에게 프로그램이 코드를 호출 sumUp 우는 계속 대단히 감사합니다절차가 완료된 후에도 프로그램이 계속되지 않는 이유는 무엇입니까 (emu8086)?

; multi-segment executable file template. 

data segment 
    message1 db "Enter 2 number..$" 

    num1 db 0 
    num2 db 0   
    suma dw 0 

ends 

stack segment 
    dw 128 dup(0) 
ends 

code segment 

    sumUp proc 

     pop bx 
     pop ax 
     sub ax,30h 

     mov suma,ax 
     pop ax  
     sub ax,30h 
     add suma,ax 

    ret 
    sumUP endp 


start: 
; set segment registers: 
    mov ax, data 
    mov ds, ax 
    mov es, ax 

; add your code here 

    lea dx,message1 
    mov ah,09h 
    int 21h 

    mov ah,1h 
    int 21h 

    mov num1,al 

    mov ah,1h 
    int 21h 

    mov num2,al 

    mov dh,0d 
    mov dl,num1 
    push dx 

    mov dh,0d 
    mov dl,num2 
    push dx 

    call sumUp  
    //I want the program to continue here after procedure is finished 

    **mov cx,0** 



ends 

end start ; set entry point and stop the assembler. 
+2

'ret' 명령은 프로 시저에서 복귀하지 않습니다. 스택에서 리턴 주소를 팝핑하고 거기서 점프합니다. 'sumUp'의 시작 부분에'pop bx'를 써서 잃어 버렸고 반환 주소를'bx'에 적재하고 다시 복원하지 않았기 때문에'ret'는 스택에서 완전히 다른 값으로 점프 할 것입니다. CPU는 프로 시저에 대해 아무 것도 이해하지 못한다.'call/ret' 명령은 스택 메모리를 사용하여이를 모방하지만 스택 구조를 올바로 유지하는 한 작동한다. – Ped7g

+0

그리고 스택 - 인 호출 규칙에서 인수를로드하는 더 일반적인 방법은 함수 프롤로그를 사용하는 것입니다 :'push bp''mov bp, sp' ... proc 본문과 함께 계속 ...'mov ax, [bp +4]; arg1'' add ax, [bp + 6]; arg2'' 서브 액스, 2 * '0''' mova, ax' 그리고 스택을 복원하는 에필로그로 끝나는'movsp, bp; 만약 sp가 정확하다면'pop bp'' ret' .. 아니면'ret by '후에 스택에서 두 개의 인자 (4B)를 제거하기 위해 "proc로 제거 된 arg"를 시뮬레이트 할 수 있습니다. – Ped7g

답변

0

push bx 추가해야합니다 :

code segment 

    sumUp proc 

     pop bx 
     pop ax 
     sub ax, 30h 

     mov suma, ax 
     pop ax 
     sub ax, 30h 
     add suma, ax 

     push bx ; needs to be added here 
    ret 
    sumUP endp 
+0

이렇게하면 호출자의 'sp'가 수정됩니다. 어떤 호출 규칙은 호출 수신자에게 args를 스택에서 제외 시키지만, 일반적으로 'ret 4'(리턴 주소를 pop 한 후에'add sp, 4'와 같은 일을한다)로 끝난다. 귀하의 호출자가 귀하의 기능을 기대하지 않는다면, 좋지 않습니다. 귀하의 기능은 매우 비효율적입니다, BTW. 'suma '에 저장하는 대신 두 개의 다른 레지스터에 팝업해야합니다. 또는 스택 프레임을 만들어 스택 메모리에 임의 액세스 할 수 있도록하십시오. –

1

당신은 스택에 리턴 어드레스를 엉망으로하고을은 그래서 거기에없는 n ret은 (IP에) 그것을 팝하고 싶어합니다.

스택의 데이터에 액세스하기 위해 팝핑하는 대신 기본 포인터로 스택 메모리에 액세스 할 수 있도록 bp을 프레임 포인터로 설정하십시오.

발신자의 bp을 저장/복원해야합니다. 일반적으로 푸시/팝을 사용하지만이 경우 함수가 간단하고 여러 임시 레지스터가 필요하지 않기 때문에이 경우 cx에 저장합니다 (저장/복원 할 필요가 없음).

; multi-segment executable file template. 

data segment 
    message1 db "Enter 2 number..$" 
ends 

stack segment 
    dw 128 dup(0) 
ends 

code segment 

    ; inputs: first arg in AX, 2nd arg on the stack 
    ; clobbers: CX 
    ; returns in: AX 
    sumUp proc 

     mov cx, bp  ; save caller's BP 
     mov bp, sp 
     mov ax, ss:[bp+2] ; get the value of pushed parameter without messing with top of the stack   
     mov bp, cx  ; restore it. 

     ret 

    sumUP endp 

start: 
; set segment registers: 
    mov ax, data 
    mov ds, ax 
    mov es, ax 

; add your code here 

    lea dx,message1 
    mov ah,09h 
    int 21h 

    mov ah,1h 
    int 21h   

    mov ah, 0 
    sub al, 30h 

    push ax 

    mov ah,1h 
    int 21h 

    mov ah, 0 
    sub al, 30h 
    ; no need to push second operand because its already in ax 
    call sumUp        

    ; result in ax 

    mov ah, 04ch 
    int 21h 

ends 

end start ; set entry point and stop the assembler. 
+0

@Peter Cordes이 코드는 어떻게 최적화 되었습니까? : D – Ahtisham

+0

꽤 끔찍한 것 같습니다. 'ret'를 사용할 수 있도록 스택 프레임을 정상적인 방법으로 만드십시오 (그리고 호출자의'bp '를 저장하는 것을 잊지 마십시오). 당신이'jmp resume'을 사용하려고한다면'call'을 전혀 사용하지 않을 것이며, 불일치 한 call/ret는 리턴 주소 예측기 스택을 깰 수 있습니다. 그래서 이것을 한 후에 나중에'ret' 명령들에서 분기 예측 오류를 얻을 것입니다. . –

+0

'[bp]'의 기계어 인코딩은 disp8 = 0, 즉'[bp + 0]'(16 비트가 32 비트와 같은 경우)에 여분의 바이트가 필요합니다. [bp]'변위없이. 스택 프레임을 정상적인 방법으로 만들면,'[bp]'는 호출자의'bp '값을 가리킨다. 접근 할 필요가 없다. 따라서'[bp + 4]'를 사용하여 첫번째 arg에 접근 할 수있다. ('ax'에서 첫 번째를 넘긴다면 2 번째). 그러므로 당신은'push bp' /'mov bp, sp' /'add ax, [bp + 4]'(SS : BP에 암시 적 임) /'pop bp' /'ret'를 사용해야합니다. ('leave'도 작동하지만'sp'는 수정하지 않았다.) –