汇编语言-x86从实模式到保护模式8.3.7的加载用户程序(加载器)问题请教各位汇编大神。下面的程序有错吗?

请问各位汇编大神,下面的加载器程序有错吗?为什么加载不到用户程序?我是写进虚拟机硬盘的,用汇编语言-x86从实模式到保护模式推荐的写虚拟硬盘程序写进去的 shu_1 equ 100 ;声明常数section mbr align=16 vstart=0x7c00start:;设置堆栈段和指针主mov dx,0mov ss,dxmov sp,dx;---mov ax,[cs:kaishidizhi] ;计算用于加载用户程序的逻辑段mov dx,[cs:kaishidizhi+0x02]mov bx,16div bxmov ds,ax ;令DS和ES指向该段以进行操作mov es,ax;---以下读取程序的起始部分xor di,dixor bx,bx ;加载到DS:0x0000处mov si,shu_1 ;程序在硬盘上的起始逻辑扇区号call read_hard_disk_0 ;---以下判断整个程序有多大(有多少个扇区)mov ax,[0] mov dx,[2]mov bx,512 ;512字节每扇区div bxcmp dx,0jnz @1 ;未除尽,因此结果比实际扇区数少1dec ax ;已经读了一个扇区,扇区总数减1;---@1:cmp ax,0 ;考虑实际长度小于等于512个字节的情况jz rukuoduan;读取剩余的扇区push ds ;以下要用到并改变DS寄存器mov cx,ax ;循环次数(剩余扇区数)@2:mov ax,dsadd ax,0x20 ;得到下一个以512字节为边界段地址mov ds,axxor bx,bx ;每次读时,偏移地址始终为0x0000inc si ;下一个逻辑扇区call read_hard_disk_0 loop @2 ;循环读,直到读完整个功能程序pop ds ;恢复数据段基址到用户程序头部段;----计算入口点代码段基址rukuoduan:mov ax,[0x06]mov dx,[0x08]call xiugaiduanmov [0x06],ax ;回填修正后的入口点代码段基址;---开始处理段重定位表mov cx,[0x0a] ;需要重定位的项目上数量mov bx,0x0c ;重定位表首地址@03:mov ax,[bx]mov dx,[bx+0x02] ;32位地址的高16位call xiugaiduanmov [bx],ax ;回真段的基址add bx,4 ;下一个重定位项(每项占4个字节)loop @03;---jmp far [0x04] ;转移到用户程序;--------------------------------------read_hard_disk_0: ;从硬盘读取一个逻辑扇区push ax ;输入:DI:SI=起始逻辑扇区号push bx ; DS:BX=目标缓冲区地址push cxpush dxmov dx,0x1f2mov al,1 out dx,al ;读取的扇区数inc dx ;0x1f3mov ax,siout dx,al ;LBA地址0~7inc dx ;0x1f4mov al,ahout dx,al ;LBA地址8~15inc dx ;0x1f5mov ax,diout dx,al ;LBA地址16~23inc dx ;0x1f6mov al,0xe0 ;LBA28模式,主盘or al,ah ;LBA地址24~27out dx,alinc dx ;0x1f7mov al,0x20 ;读命令out dx,al;----waits:in al,dxand al,0x88cmp al,0x08jnz waits ;不忙,且硬盘已准备好数据传输mov cx,256 ;总共要读取的字数mov dx,0x1f0dushuju:in ax,dxmov [bx],axadd bx,2loop dushujupop dxpop cxpop bxpop axret;---------------------------------xiugaiduan: ;计算16位段地址push dx ;输入:DX:AX=32位物理地址 ;返回:AX=16位段基地址add ax,[kaishidizhi]adc dx,[kaishidizhi+0x02]shr ax,4ror dx,4and dx,0xf000or ax,dxpop dxret;--------------------------------kaishidizhi dd 0x10000 ;用户程序被加载的物理起始地址times 510-($-$$) db 0 db 0x55,0xaa
2026年09月28日 17:23
有1个网友回答
网友(1):

你对硬盘的io操作不知道你的虚拟机是否支持?
你改成用int 13h试试?