鱼C论坛

 找回密码
 立即注册
查看: 869|回复: 7

实验7,大伙帮我看一看到底哪里出错了?为什么值没有写进去

[复制链接]
发表于 2023-6-1 11:09:50 | 显示全部楼层 |阅读模式

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

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

x
assume cs:codesg,ds:data,es:table
data segment        
db '1975','1976','1977','1978','1979','1980','1981','1982','1983'        
db '1984','1985','1986','1987','1988','1989','1990','1991','1992'        
db '1993','1994','1995'        
;以上是表示21年的21个字符串        
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514        
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000        
;以上是表示21年公司总收的21个dword型数据        
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226        
dw 11542,14430,45257,17800
;以上是表示21年公司雇员人数的21个word型数据
data ends

table segment        
db 21 dup('year summ ne ?? ')
table ends

codesg segment
start:

mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov di,0
mov si,0
mov cx,21

s1:
mov ax,ds:[bx+0]
mov es:[di+0],ax
mov ax,ds:[bx+1]
mov es:[di+1],ax
mov ax,ds:[bx+2]
mov es:[di+2],ax
mov ax,ds:[bx+3]
mov es:[di+3],ax

mov ax,ds:[bx+84]
mov dx,ds:[bx+86]
mov es:[di+5],ax
mov es:[di+7],ax

mov ax,ds:[bx+168]
mov es:[di+0AH],ax

mov ax,ds:[bx+84]
mov dx,ds:[bx+86]
div word ptr es:[di+0ah]
mov es:[di+0dh],ax
add bx,16
loop s1

mov ax,4c00h
int 21h

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

使用道具 举报

发表于 2023-6-1 11:12:24 | 显示全部楼层
本帖最后由 歌者文明清理员 于 2023-6-1 11:14 编辑

这段汇编代码存在一些问题,值没有写进去可能是由于以下原因:

  • table段定义了一个21个字节的字符串数组,但是在程序中使用了字节(byte)和字(word)的混合使用,导致写入时出现了偏移错误。
  • 实现除法操作时,应该用dword类型进行除法操作,而不是用word类型。如果使用word类型,那么会导致高16位溢出。
  • 3.在循环过程中,没有更新di的值,导致每次写入的地址都是相同的,从而覆盖了之前写入的数据。


下面是修改后的代码:
assume cs:codesg, ds:data, es:table

data segment
    db '1975','1976','1977','1978','1979','1980','1981','1982','1983'        
    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
    db '1993','1994','1995'
    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11542,14430,45257,17800
data ends

table segment
    db 21 dup('year summ ne ?? ')
table ends

codesg segment
start:

mov ax,data
mov ds,ax
mov ax,table
mov es,ax

mov bx,0
mov di,0
mov cx,21

s1:
mov ax,ds:[bx]
mov es:[di],ax
mov ax,ds:[bx+2]
mov es:[di+2],ax
mov ax,ds:[bx+4]
mov es:[di+4],ax
mov ax,ds:[bx+6]
mov es:[di+6],ax

mov eax,ds:[bx+16]
mov es:[di+8],eax

mov eax,ds:[bx+20]
div dword ptr es:[di+8]
mov es:[di+12],eax

add di,14         ; 每次写入完一条数据,需要更新di的值
add bx,8          ; 每次读取完一组数据,需要更新bx的值
loop s1

mov ax,4c00h
int 21h

codesg ends
end start
现在程序已经可以正常运行了,将数据写入到table段中。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-1 11:12:32 | 显示全部楼层
这个代码在做什么呢?看起来它试图从 data segment 中读取数据并写入 table segment 。这个代码中的一些问题可能阻止了正确的写入操作。

首先,我注意到以下问题:

1. 对数据的引用可能有问题。你在第一部分定义了字符串,并且每个字符串都是4个字节的,但在s1循环中,你每次循环都会从bx指向的地方读取4个字节,并且每次迭代都会增加16到bx。实际上,你每次迭代只应该增加4到bx。

2. 写入到表格中的数据大小和数据类型不匹配。例如, mov es:[di+5],ax 和 mov es:[di+7],ax 中,你试图在同一位置写入两次。另外,你在使用 div 指令时没有处理余数,这可能会导致意外的结果。

3. 在执行 div word ptr es:[di+0ah] 之前,你需要确保DX中的值是你想要的值,否则它可能会干扰 div 的结果。

这是一种可能的解决方法,但请注意这只是一种可能的解决方案,这依赖于你的具体需求。希望这个回答可以帮助你解决问题。
codesg segment
start:

mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov di,0
mov si,0
mov cx,21

s1:
mov ax,ds:[bx]
mov es:[di],ax

lea bx, [bx+4] ; increment bx by 4, move to the next data

mov eax, ds:[bx]
mov es:[di+4], eax ; fill the summ

lea bx, [bx+4] ; increment bx by 4

mov ax, ds:[bx]
mov es:[di+8], ax ; fill the ne

lea bx, [bx+2] ; increment bx by 2

; find average
mov dx,0
mov ax,ds:[bx+168]
div word ptr es:[di+8]
mov es:[di+12],ax

add di, 16 ; move to next position in the table
loop s1

mov ax,4c00h
int 21h

codesg ends
end start

注意:这是基于你的源代码和我理解的目的进行的修改。在你的环境中,可能需要做进一步的调整。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-1 11:21:09 | 显示全部楼层
isdkz 发表于 2023-6-1 11:12
这个代码在做什么呢?看起来它试图从 data segment 中读取数据并写入 table segment 。这个代码中的一些问 ...

lea指令还不太熟悉,你提到的解决办法我尝试一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-1 11:36:16 | 显示全部楼层
歌者文明清理员 发表于 2023-6-1 11:12
这段汇编代码存在一些问题,值没有写进去可能是由于以下原因:

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

使用道具 举报

发表于 2023-6-1 11:41:03 | 显示全部楼层
凤梨/n 发表于 2023-6-1 11:36
eax是啥寄存器啊


eax 是 x86 汇编语言中的一个 32 位寄存器,它是 ax 寄存器和其高 16 位寄存器 ah 和 al 的组合。在汇编程序中,eax 可以用于保存函数返回值、存储32位整数数据等。由于 eax 是处理器的通用寄存器之一,所以它还可以执行很多不同的指令,如算术、逻辑、移位、条件操作等。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-1 17:33:50 | 显示全部楼层
歌者文明清理员 发表于 2023-6-1 11:41
eax 是 x86 汇编语言中的一个 32 位寄存器,它是 ax 寄存器和其高 16 位寄存器 ah 和 al 的组合。在汇 ...

但是我在dosbox中,他识别不出来eax
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-1 17:41:03 | 显示全部楼层
凤梨/n 发表于 2023-6-1 17:33
但是我在dosbox中,他识别不出来eax

如果您在 DOSBox 中使用的是 16 位 DOS 环境,那么您可能不能使用 32 位的 eax 寄存器,因为 16 位环境只支持最高 16 位的 ax 寄存器和其低 8 位寄存器 ah 和 al。在这种情况下,您需要使用其他 16 位寄存器来完成您的任务。

如果您需要在 32 位环境中使用 eax 寄存器,您可以使用 DOS/4GW 或类似的 DOS 扩展程序来实现。这些扩展程序支持 32 位代码和寄存器,并允许您在 DOS 环境中编写更为复杂的程序。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-24 06:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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