6YKT6ZKm5LqI 发表于 2022-7-11 22:57:05

实验十

问题: 执行到div指令也就是第25行的时候就会莫名跳转到别的地方,如图

代码如下:
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:   ; 跳过前面七行
      mov bx, es
      add ax, bx
      sub cl, 1
      add al, cl; 跳过前面两列
      div word ptr ds: ; 商存放到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: ; 取出字符
      jcxz ok ; 判断字符是否为0
      mov es:, cl
      inc di ; 定位下一个目的地址
      inc si ; 定位下一个字符
      mov al, ds: ; 取出字符属性
      mov es:, al
      inc di
      jmp short show_str
    ok:
      ret
codesg ends
end start

jackz007 发表于 2022-7-11 23:43:45

         你这个代码的意图是什么,用直接写屏技术,按照 4ah 的显示属性,把字符串 'hard hard study day day up' 显示到屏幕上的第 8 行,第 3 列开始的位置?

人造人 发表于 2022-7-12 09:09:44

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

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

B8462 / A 的商是 126D6
余数是 6
执行完 div word ptr 后,把商 126D6 存放在AX寄存器中,把余数 6 存放在DX寄存器中
但是你有没有发现一个问题?
把商 126D6 存放在AX寄存器中
AX可以保存下 126D6 吗?
没错,除法溢出了,可以想到 F000:1060 的位置是除法溢出的处理程序

人造人 发表于 2022-7-12 09:27:53

中断处理程序的那个 fe 38 确实不知道是什么
我看了一下我这边
如果没有运行dos操作系统,这个除法溢出中断的位置只有一个 iret
如果运行dos操作系统,这个位置就是dos提供的除法溢出中断的处理程序,由nop指令开始
(0) 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) 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) 0000:7c00 (unk. ctxt): jmp .+60(0x00007c3e)    ; eb3c
<bochs:6> c
^CNext at t=594620446
(0) 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>

人造人 发表于 2022-7-12 09:37:06

看这个除法溢出处理程序的地址由F开头,也就是这个除法溢出处理程序是由bios rom提供的,你用的哪个版本的 bios rom

6YKT6ZKm5LqI 发表于 2022-7-12 10:14:22

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

题目:

下次我一定记得发题目{:10_282:}
我用的dosbox,我不太了解bios rom,我查了一下电脑的bios版本:

6YKT6ZKm5LqI 发表于 2022-7-12 10:21:18

本帖最后由 6YKT6ZKm5LqI 于 2022-7-12 10:27 编辑

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

啊,这个除法我想错了,我以为这个除法的商就是b846,然后余数是2{:10_285:}, 问题应该就在这里,我去改改看还有没有问题

人造人 发表于 2022-7-12 10:31:51

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

人造人 发表于 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"


canfeng0522 发表于 2022-7-12 11:50:30

{:10_264:}

kerln888 发表于 2022-7-12 12:17:05

{:10_256:}{:10_256:}{:10_256:}

Adam.yu 发表于 2022-7-13 09:09:25

{:10_277:}
页: [1]
查看完整版本: 实验十