admin管理员组

文章数量:1357615

I'm working on writing a monitor program for the 8086 using a mix of C and Assembly. While exploring available tools, I came across Slador's toolchain, which I found incredibly useful Hello World!.

To test different execution flows, I simulated the 8086 using Proteus. However, I observed an unexpected behavior when calling functions from main():

Issue: Function Return to the Start of main() The program’s entry point is

RESET: → jmp init → call main().

Inside main(), whenever a function is called, instead of returning to the instruction after the call, execution jumps back to the start of main().

  1. rest.asm (Entry Point - Calls init)
        CPU 8086
        BITS 16

        %include "system_def.inc"

        SECTION .reset

        GLOBAL reset
        EXTERN init

reset:
        jmp SYSTEM_BOOT_SEG:init
  1. init.m (Initializes Stack & Calls main)
            CPU 8086
        BITS 16

        %include "system_def.inc"

        SECTION .text

        GLOBAL init

        EXTERN __dataoffset
        EXTERN __ldata
        EXTERN __sbss
        EXTERN __lbss

        EXTERN main

init:
        mov ax, SYSTEM_STACK_SEG
        mov ss, ax
        xor sp, sp
        mov es, ax

        mov ax, cs
        mov ds, ax

        mov si, __dataoffset
        xor di, di
        mov cx, __ldata
        rep movsw

        xor ax, ax
        mov di, __sbss
        mov cx, __lbss
        rep stosw

        mov ax, ss
        mov ds, ax
        mov es, ax

        call main
        jmp $
  1. main.c (Example Code)

     #include <stdint.h>
     #include <stdbool.h>
     #include <string.h>
     #include "utils.h"
     #include "text_lcd.h"
    
     void lcd_init() {
     delay(2000);  // Code gets stuck here
     ...
     }
    
     void main() {
     lcd_init();
     char buffer[16] = "Hello World!";
     text_lcd_send_text_at(4, 1, buffer);
     }
    
  2. delay Function (Assembly)

         delay:
         push bp
         mov bp, sp
    
         mov cx, [bp + 4]
         .1:     dec cx
         jnz .1
    
         mov sp, bp
         pop bp
         ret
    

Experiment & Findings: When I modified the flow by placing a jmp main before init, the issue was resolved—functions returned correctly to their respective calling points.

This makes me suspect the issue might be related to stack initialization or how the execution environment is set up.

Questions: Could this be a limitation or quirk of the Proteus 8086 simulation, meaning real hardware would behave correctly?

I noticed in Slador’s video that the code runs correctly on an actual 8088 system—does this confirm that the behavior I'm seeing is just a simulation artifact?

I appreciate any insights from those experienced with real 8086 hardware or debugging in Proteus.

本文标签: nasmIssue with Function Return Behavior in 8086 Monitor Code (C amp Assembly)Stack Overflow