求助各位汇编大神!!!

juge0007 2019-03-01 10:46:08
今天调试这个程序,搞了一晚上没个结果
我在做王爽汇编的课程设计2

这个是我读取软盘的程序
assume cs:code

data segment
db 512 dup (0)
data ends

code segment
start:
mov ax,cs
mov ds,ax
mov si,offset bootstart

mov ax,data
mov es,ax
mov di,0

mov cx,offset bootend - offset bootstart
cld
rep movsb

jmp write

bootstart:
jmp short boots ;问题A
db 10 dup (0)

boots:
mov ax,cs ;问题B
mov ss,ax
mov sp,10

mov ax,0
mov es,ax
mov bx,7c00h

mov al,1
mov ch,0
mov cl,2
mov dl,0
mov dh,0
mov ah,2

int 13h

mov bx,0
push bx
mov bx,7c00h
push bx
retf

bootend: nop

write:
mov ax,data
mov es,ax
mov bx,0

mov al,1
mov ch,0
mov cl,1
mov dl,0
mov dh,0
mov ah,3
int 13h

mov ax,4c00h
int 21h
code ends
end start


有两个问题:
1、问题A:为什么在程序bootstart刚开始的时候要用一个jmp short boots跳转,只看代码的话,照理来说定义了数据以后也会去执行boots后面的语句啊?
2、问题B:这段在对sp赋值的时候,网上答案是直接给的mov sp,10,但是我觉得10这个值不够准确,因为前面有个jmp指令,应该占了两个字节,所以我觉得应该是mov sp,12才对,因此我想让程序自动去获取到底应该mov sp几个字节,所以我把它改成了mov sp,offset boots-offset bootstart,但是这么一改,就执行不正确了

关于参考的程序是来自这个连接的:
https://www.jianshu.com/p/0a99d34113c0
还请各位汇编大神指导指导

难道mov sp只能用数字去赋值吗?我试过
mov bx,10
mov ax,cx
mov ss,ax
mov sp,bx
也是不行的
也不是说不行,就是运行了程序以后,得不出想要的结果来
...全文
290 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
为什么是7c00呢,因为7c00h=8000h-400h(1024),是32KB地址的最高1KB,32KB RAM是IBM PC带软驱系统的最小RAM配置,高地址的1KB是用来加载磁盘引导扇区的,之所以使用1KB缓冲区而不是512字节,是因为软盘扇区大小是可调节的,BIOS INT13h格式化道功能支持128/256/512/1024四种扇区大小。
如果ss是7c00h,那需要至少496KB RAM才能引导成功,早期PC没有这么多内存。
juge0007 2019-03-05
  • 打赏
  • 举报
回复
引用 2 楼 早打大打打核战争 的回复:
应该是0000:7c00,虽然在实模式下0000:7c00=07c0:0000,但是在MBR和DOS引导扇区的代码中都直接使用了7c00的偏移地址,MBR中设置sp为7c00,DOS 5.0的引导扇区中设置sp为7bf4

你说的这个可能是对的,我今天好好试了试,把boots中
mov ax,0
mov es,ax
mov bx,7c00h
改为
mov ax,7c00h
mov es,ax
mov bx,0
就得不到想要的结果了
另外想问下,为什么sp是7c00h,不应该ss是7c00h吗?

还有一个不明白的地方是,用int 13h写入磁盘,al设置写入的扇区数,系统怎么知道我要让他写多少个字节?如果我不把代码赋值进data段中,而是直接将bootstart处的内容写入,会不会存在将write段中代码写入到磁盘的情况
juge0007 2019-03-05
  • 打赏
  • 举报
回复
引用 6 楼 zara 的回复:
bootstart: 后是你的软盘引导,是要被加载到 0000:7C00 处执行的,你在其中又读入了扇区到 0000:7C00 就把其覆盖了,所以无法正常运作的。有这要求,可以参考硬盘 MBR 的做法,就是先把自己复制到其它地方,转移到复制后的地方,再加载扇区到 0000:7C00 处,处理完后跳转过去。这些正确了后再来斟酌 sp 等的用法。
另外,你的引导部分都没有必要的引导标记,看来用的虚拟机不大严格。

加个QQ吧,还是没太看懂啊
zara 2019-03-05
  • 打赏
  • 举报
回复
bootstart: 后是你的软盘引导,是要被加载到 0000:7C00 处执行的,你在其中又读入了扇区到 0000:7C00 就把其覆盖了,所以无法正常运作的。有这要求,可以参考硬盘 MBR 的做法,就是先把自己复制到其它地方,转移到复制后的地方,再加载扇区到 0000:7C00 处,处理完后跳转过去。这些正确了后再来斟酌 sp 等的用法。
另外,你的引导部分都没有必要的引导标记,看来用的虚拟机不大严格。
  • 打赏
  • 举报
回复
不覆盖也不行,会导致文件系统错误,因为软盘文件系统通常格式化为FAT12,其保留扇区数默认为1,FAT之前只有一个引导扇区,这样你把原引导扇区备份到0:0:2会破坏FAT1,磁盘写入文件后还会破坏原引导扇区,下次就启动不了
zara 2019-03-04
  • 打赏
  • 举报
回复
1. 定义了数据,是给你、给编译器看的,cpu 可不认,只会顺序执行,没有 jmp 指令会把数据当指令执行的。有些编译器可能提供伪语句来实现 jmp+db/dd 功能。
2. 感觉你这里的 10 是有问题的。引导扇区应该是被加载到 0000:7C00 处吧,还是现在有新的约定了是 07C0:0000?至于是 10 还是 12 问题倒不大,只要不淹没当前待执行的代码部分。sp 赋值,没有模式要求吧;结果不对,可以在疑问处加些功能输出想看的信息以判断问题在哪。
juge0007 2019-03-04
  • 打赏
  • 举报
回复
引用 2 楼 早打大打打核战争 的回复:
应该是0000:7c00,虽然在实模式下0000:7c00=07c0:0000,但是在MBR和DOS引导扇区的代码中都直接使用了7c00的偏移地址,MBR中设置sp为7c00,DOS 5.0的引导扇区中设置sp为7bf4

这我试过了,还是不行 ,问题还是出在mov sp处
juge0007 2019-03-04
  • 打赏
  • 举报
回复
引用 2 楼 早打大打打核战争 的回复:
应该是0000:7c00,虽然在实模式下0000:7c00=07c0:0000,但是在MBR和DOS引导扇区的代码中都直接使用了7c00的偏移地址,MBR中设置sp为7c00,DOS 5.0的引导扇区中设置sp为7bf4


你意思是程序后面,应该先把7c00 push进去?
juge0007 2019-03-04
  • 打赏
  • 举报
回复
引用 1 楼 zara 的回复:
1. 定义了数据,是给你、给编译器看的,cpu 可不认,只会顺序执行,没有 jmp 指令会把数据当指令执行的。有些编译器可能提供伪语句来实现 jmp+db/dd 功能。
2. 感觉你这里的 10 是有问题的。引导扇区应该是被加载到 0000:7C00 处吧,还是现在有新的约定了是 07C0:0000?至于是 10 还是 12 问题倒不大,只要不淹没当前待执行的代码部分。sp 赋值,没有模式要求吧;结果不对,可以在疑问处加些功能输出想看的信息以判断问题在哪。


是想把开机跳转至0:7c00处,这不好调试吧,我反复开机关机试了很多次,sp用数字时,是可以的,用offset就不正确了,有点奇怪
  • 打赏
  • 举报
回复
应该是0000:7c00,虽然在实模式下0000:7c00=07c0:0000,但是在MBR和DOS引导扇区的代码中都直接使用了7c00的偏移地址,MBR中设置sp为7c00,DOS 5.0的引导扇区中设置sp为7bf4

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧