鱼C论坛

 找回密码
 立即注册
查看: 1708|回复: 11

[已解决]实验十

[复制链接]
发表于 2022-7-11 22:57:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
问题: 执行到div指令也就是第25行的时候就会莫名跳转到别的地方,如图
1.png
代码如下:
assume cs: codesg, ds: data

data segment
    db 'hard hard study day day up', 0
    db 4ah, 0a0h, 0ah, 0 ; 4ah为字符串属性(偏移地址为1bh), 0a0h是160的16进制(偏移地址为1ch), 0ah是10的16进制(偏移地址为1dh)
data ends

codesg segment
    start:
        mov ax, data
        mov ds, ax
        mov ch, 8 ; 设置显示位置为第八行
        mov cl, 3 ; 设置显示位置为第三列
        mov ax, 8000h
        mov dx, 0bh ; 显存物理地址为b8000, 用dx存放高位,ax存放低位
        mov es, ax 
        xor ax, ax
        sub ch, 1 
        mov al, ch
        mul byte ptr ds:[1ch]   ; 跳过前面七行
        mov bx, es
        add ax, bx 
        sub cl, 1
        add al, cl; 跳过前面两列
        div word ptr ds:[1dh] ; 商存放到ax, 余数存放到dx
        mov di, dx ; 将初始偏移地址赋给di
        mov es, ax ; 将目的段地址赋给es
        xor si, si ; si用于索引字符串
        call show_str
        mov ax, 4c00h
        int 21h
    show_str:
        mov ch, 0 ; 利用cx判断是否到达字符串末端
        mov cl, ds:[si] ; 取出字符
        jcxz ok ; 判断字符是否为0
        mov es:[di], cl 
        inc di ; 定位下一个目的地址
        inc si ; 定位下一个字符
        mov al, ds:[1bh] ; 取出字符属性
        mov es:[di], al
        inc di
        jmp short show_str
    ok:
        ret 
codesg ends
end start
最佳答案
2022-7-12 09:09:44
1. 实验十是什么?把题目发出来呀
你不发出来,让别人去找你问题的题目,这样太费时间了
解决你的问题也就几分钟的时间,去找你问题的题目的时间,至少十几分钟,这是至少
我学完汇编语言已经过去很长很长时间了,不可能记得实验十是什么
学汇编语言的时候用的还是windows系统(已经忘了是windows几了),现在已经用linux系统了
我要找到之前学汇编语言的那些资料的难度至少在半个小时以上
也就是说,你不把题目发出来,而是让我们自己去找
那我们很有可能会放弃回答这个问题,毕竟要花的时间实在是太多了

2. 看你的图片中
div 是 DX:AX / DS:[1D]
就是16位除法
DX:AX 的内容是 B8462
DS:[1D] 的内容是 A

B8462 / A 的商是 126D6
余数是 6
执行完 div word ptr [001d] 后,把商 126D6 存放在AX寄存器中,把余数 6 存放在DX寄存器中
但是你有没有发现一个问题?
把商 126D6 存放在AX寄存器中
AX可以保存下 126D6 吗?
没错,除法溢出了,可以想到 F000:1060 的位置是除法溢出的处理程序
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-11 23:43:45 | 显示全部楼层

回帖奖励 +4 鱼币

         你这个代码的意图是什么,用直接写屏技术,按照 4ah 的显示属性,把字符串 'hard hard study day day up' 显示到屏幕上的第 8 行,第 3 列开始的位置?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-12 09:09:44 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +4 鱼币

1. 实验十是什么?把题目发出来呀
你不发出来,让别人去找你问题的题目,这样太费时间了
解决你的问题也就几分钟的时间,去找你问题的题目的时间,至少十几分钟,这是至少
我学完汇编语言已经过去很长很长时间了,不可能记得实验十是什么
学汇编语言的时候用的还是windows系统(已经忘了是windows几了),现在已经用linux系统了
我要找到之前学汇编语言的那些资料的难度至少在半个小时以上
也就是说,你不把题目发出来,而是让我们自己去找
那我们很有可能会放弃回答这个问题,毕竟要花的时间实在是太多了

2. 看你的图片中
div 是 DX:AX / DS:[1D]
就是16位除法
DX:AX 的内容是 B8462
DS:[1D] 的内容是 A

B8462 / A 的商是 126D6
余数是 6
执行完 div word ptr [001d] 后,把商 126D6 存放在AX寄存器中,把余数 6 存放在DX寄存器中
但是你有没有发现一个问题?
把商 126D6 存放在AX寄存器中
AX可以保存下 126D6 吗?
没错,除法溢出了,可以想到 F000:1060 的位置是除法溢出的处理程序
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-12 09:27:53 | 显示全部楼层
中断处理程序的那个 fe 38 确实不知道是什么
我看了一下我这边
如果没有运行dos操作系统,这个除法溢出中断的位置只有一个 iret
如果运行dos操作系统,这个位置就是dos提供的除法溢出中断的处理程序,由nop指令开始
(0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b          ; ea5be000f0
<bochs:1> b 0x7c00
<bochs:2> c
(0) Breakpoint 1, 0x0000000000007c00 in ?? ()
Next at t=412124554
(0) [0x000000007c00] 0000:7c00 (unk. ctxt): xor ax, ax                ; 33c0
<bochs:3> info ivt 0
INT# 00 > F000:FF53 (0x000fff53) DIVIDE ERROR ; dummy iret
<bochs:4> u/3 0x000fff53
00000000000fff53: (                    ): iret                      ; cf
00000000000fff54: (                    ): mov dx, 0x0400            ; ba0004
00000000000fff57: (                    ): mov ax, 0x2e06            ; b8062e
<bochs:5> c
(0) Breakpoint 1, 0x0000000000007c00 in ?? ()
Next at t=412126790
(0) [0x000000007c00] 0000:7c00 (unk. ctxt): jmp .+60  (0x00007c3e)    ; eb3c
<bochs:6> c
^CNext at t=594620446
(0) [0x000000000e43] 0070:0743 (unk. ctxt): cmp byte ptr cs:0x000d, 0x00 ; 2e803e0d0000
<bochs:7> info ivt 0
INT# 00 > 0116:108A (0x000021ea) DIVIDE ERROR
<bochs:8> u/3 0x000021ea
00000000000021ea: (                    ): nop                       ; 90
00000000000021eb: (                    ): nop                       ; 90
00000000000021ec: (                    ): call .+224  (0x000022cf)  ; e8e000
<bochs:9>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-12 09:37:06 | 显示全部楼层
看这个除法溢出处理程序的地址由F开头,也就是这个除法溢出处理程序是由bios rom提供的,你用的哪个版本的 bios rom
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-12 10:14:22 | 显示全部楼层
人造人 发表于 2022-7-12 09:09
1. 实验十是什么?把题目发出来呀
你不发出来,让别人去找你问题的题目,这样太费时间了
解决你的问题也 ...

题目:
3.png
下次我一定记得发题目
我用的dosbox,我不太了解bios rom,我查了一下电脑的bios版本:
2.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-12 10:21:18 | 显示全部楼层
本帖最后由 6YKT6ZKm5LqI 于 2022-7-12 10:27 编辑
人造人 发表于 2022-7-12 09:09
1. 实验十是什么?把题目发出来呀
你不发出来,让别人去找你问题的题目,这样太费时间了
解决你的问题也 ...


啊,这个除法我想错了,我以为这个除法的商就是b846,然后余数是2, 问题应该就在这里,我去改改看还有没有问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-12 10:31:51 | 显示全部楼层
6YKT6ZKm5LqI 发表于 2022-7-12 10:21
啊,这个除法我想错了,我以为这个除法的商就是b846,然后余数是2, 问题应该就在这里,我去 ...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-12 11:23:24 | 显示全部楼层
6YKT6ZKm5LqI 发表于 2022-7-12 10:14
题目:

下次我一定记得发题目

你理解错题意了,题目是要你写一个show_str的函数(子程序),把字符串用指定的颜色显示到指定的位置
把字符串用指定的颜色显示到指定的位置,这件事全部由show_str这个函数来做
我调用这个函数的时候,告诉这个函数 行号、列号、颜色和字符串的首地址,这个函数用这些信息把字符串正确的显示出来
像下面这样的

我从前的汇编语言学习环境不能用了(或者说成是要用这个环境的代价太高了)
我用现在的汇编语言学习环境给你写了一下这个题目,你可以看看
    .code16
    .globl  _start
_start:
    pushw   $0x07c0
    popw    %ds

    movb    $11, %dh
    movb    $34, %dl
    movb    $2, %cl
    movw    $str0, %si
    callw   show_str

    movb    $13, %dh
    movb    $24, %dl
    movb    $4, %cl
    movw    $str1, %si
    callw   show_str

1:  cli
    hlt
    jmp 1b

# 名称:show_str
# 功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串
# 参数:(dh)=行号(取值范围0~24)
#       (dl)=列号(取值范围0~79)
#       (cl)=颜色
#       ds:si指向字符串的首地址
# 返回:无
show_str:
    pushw   %es
    pushw   %ax
    pushw   %di
    pushw   %si

    # dh大于24直接返回
    # dl大于79直接返回
    cmpb    $24, %dh
    ja      1f
    cmpb    $79, %dl
    ja      1f

    # di = dh * 160 + dl * 2
    movb    $160, %al
    mulb    %dh
    movw    %ax, %di
    movb    $2, %al
    mulb    %dl
    addw    %ax, %di

    # es指向显存
    pushw   $0xb800
    popw    %es

    # ah保存显示属性
    # al保存显示字符
    movb    %cl, %ah
2:  movb    (%si), %al      # 从ds:si的位置取一个字符到al
    incw    %si             # si += 1

    # 取到的字符是0就退出
    cmpb    $0, %al
    je      1f

    movw    %ax, %es:(%di)  # 把ax中的数据写到es:di的位置
    addw    $2, %di         # di += 2
    jmp     2b
1:
    popw    %si
    popw    %di
    popw    %ax
    popw    %es
    retw

str0:    .string "hello world!"
str1:    .string "AS - the portable GNU assembler"

1.png

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
6YKT6ZKm5LqI + 5 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-12 11:50:30 | 显示全部楼层

回帖奖励 +4 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-12 12:17:05 | 显示全部楼层

回帖奖励 +4 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-13 09:09:25 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 22:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表