489917498 发表于 2025-10-16 00:11:44

汇编实验七

哈哈,这种时隔多年发生羁绊的评论还是很让人激动的
回归正题,先给一下我的源码和结果吧(我的段定义并没有完全依照课本上,我做了一些“优化”,为了大家理解我也在旁边做了解释“
assume cs:a

b segment
dw   1975h,1976h,1977h,1978h,1979h,1980h,1983h
dw   1984h,1985h,1986h,1987h,1988h,1989h,1990h   ;这里换成16进制是为了在内存中更直观的体现出来,难度与原差异不大
dw   1991h,1992h,1993h,1994h,1995h,1996h,1997h
b ends

c segment
dd 16H,22h,382h,1356h,2390h,8000h,16000h,24486h,50065h,97479h,140417h,197514h          ;但是这里换成十六进制我想了很久,和上面不同这里换成十六进制更多是为了
dd 345980h,590827h,803530h,1183000h,1843000h,2759000h,3753000h,4649000h,5937000h    ;给ax,dx复制。因为我不知道有哪条指令可以将一个十进制化为十六进制并从中分出高低位(因为有的收入大于word型 而ax,dx都是字型)
c ends                                                                                                                                 ;所以我直接将这些收入设为十六进制,也是给大家提个醒,以后涉及到这类问题要将收入先化为十六进制.....也可能是我没学到更牛的指令

d segment
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800
d ends

table segment
dd 21 dup (0,0,0,0 );年b2 总c4 人d2 均t2      00 00 00 00,00 00 00 00,00 00 00 00,00 00 00 00      ;我通过完成这个实验也体会到了这个段内存的引用,就是不用管它是dd、dw还是db你只要指向你需要的偏移地址,如现在dd 0,0是两个双字型
table ends                                                                                                                                        ;但其实就是8个字节,你可以在0到1装一个al,2到3装一个ah。所以我后面才发现内存里面有部分零是可以不出现的,但是总收入里面为了后面还会有很多零

e segment
dw0,0,0,0,0,0
e ends


a segment
start:mov ax,c
      mov ds, ax
          mov ax,d                                                                                        ;调用总,人求均
          mov es,ax
          mov ax,e
          mov ss,ax
          mov sp,10
          
          mov bx,0
          mov si,0
          mov di,0                                                                               ;调试循环参数,bx:调取总。si:调取人数
          mov cx,21                                                                        ;cx:21组
        s:
          movax,   
          mov dx,          ;调取总的高字节和低字节
          push ax
          push dx
          
          div word ptr es:   ;调取人数
          
          push ds
      push ax                                                          ;调取t地址,由上到下 商,总段,总高,总低
          mov ax, table
          mov ds,ax
          pop                                                  ;存入均,si在t,Tt和T人不一样改为di
          pop dx                                                      ;总段放入dx
          pop                                                 ;存入总高
          pop                                              ;存入总低
          mov ax,es:                                             ;存入人数
          mov ,ax
          push es                                                          ;栈内为ren段
          mov ax,b
          mov es,ax                                                       ;es为b段
          mov ax,es:
          mov ,ax
          pop es
          mov ds,dx
          add bx,4
          add si,2
          add di,16
          loop s
          
          mov ax,4c00H
          int 21
a ends
end start
我醉了不会发图片,我只截屏了。有需要可以教我。。。


FishC 发表于 2025-10-16 00:13:18

感谢您分享汇编实验七的代码和心得!您的优化和解释很有趣,也体现了对内存管理的深入理解。以下是一些反馈和指导,希望能帮助您和其他鱼油更好地学习。


; 您的代码片段(部分不完整,我已根据上下文补充注释)
assume cs:a
; ... 段定义 ...
a segment
start:mov ax,c
      mov ds, ax
      mov ax,d
      mov es,ax
      mov ax,e
      mov ss,ax
      mov sp,10
      mov bx,0
      mov si,0
      mov di,0
      mov cx,21
    s:
      mov ax,    ; 假设这里加载总收入低字(需根据实际偏移调整)
      mov dx, ; 加载总收入高字
      push ax
      push dx
      div word ptr es: ; 除以人数(需确保es指向d段)
      ; ... 后续操作 ...
a ends
end start


代码点评:
- 将数据定义为十六进制是合理的,尤其在调试时更直观。但请注意,汇编中数字字面值(如1975)会被汇编器自动转换,无需手动转十六进制,除非有特殊需求。
- 内存引用理解正确:无论定义为何种类型(dd/dw/db),内存都是字节序列,可通过偏移地址灵活访问。
- 代码中部分指令不完整(如 mov ax, ),需根据逻辑补充操作数。例如,总收入加载可能需用 mov ax, 和 mov dx, 。
- 除法部分:确保 div word ptr es: 正确指向人数数据,并注意商和余数的处理。

关于发图片:
在Discuz!论坛发图片的常用方法是:
1. 在发帖编辑界面,点击“图片”按钮(通常是一个相机或图片图标)。
2. 选择“上传图片”,从您的电脑中选择截屏文件。
3. 上传完成后,图片会显示在编辑器中,或以BBCode标签(如 ...)形式插入。
4. 如果论坛支持附件,也可用“附件”功能上传图片,然后在帖子中引用。

注意:图片需先上传到论坛,不可直接粘贴外部链接(遵守论坛规则)。

总结:
您的代码思路清晰,优化体现了对汇编内存模型的掌握。继续加油!如果有具体错误或问题,欢迎补充细节,我会进一步解答。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

489917498 发表于 2025-10-17 13:23:33

FishC 发表于 2025-10-16 00:13
感谢您分享汇编实验七的代码和心得!您的优化和解释很有趣,也体现了对内存管理的深入理解。以下是一些反馈 ...

快救我实验九另一个帖子

FishC 发表于 2025-10-17 13:24:02

489917498 发表于 2025-10-17 13:23
FishC 发表于 2025-10-16 00:13
感谢您分享汇编实验 ...

我理解您需要紧急帮助实验九,但在这个帖子中,您分享的是实验七的代码。如果您在另一个帖子中发布了实验九的具体问题,请在那里提供更多细节(如代码、错误信息或具体困难),我会尽力协助。

如果实验九与汇编相关,这里有一些通用建议:
- 确保段定义正确,使用 assume 指令关联段与寄存器。
- 调试时,可以用 int 21h 的显示功能输出中间值。
- 如果涉及数据转换,记得汇编器会自动处理十进制数字,但手动使用十六进制可能更直观。

如果需要更具体的帮助,请在此回复中描述实验九的问题,我会用BBCode格式回复。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

489917498 发表于 2025-10-20 20:29:52

补帖子:我知道如何将一个十进制数(需32位),精准将高低16位分出来了。直接放入内存取高低位。。。看来我领悟的还是不够透

FishC 发表于 2025-10-20 20:30:31

489917498 发表于 2025-10-20 20:29
补帖子:我知道如何将一个十进制数(需32位),精准将 ...

我理解您对32位十进制数分解为高低16位的疑问。在汇编中,处理32位数(双字)时,确实需要关注内存布局和访问方式。以下是一个简洁的解释和示例:

在8086汇编中,32位数通常存储在连续的内存字节中,采用小端模式(低字节在低地址,高字节在高地址)。例如,一个32位数12345678h在内存中的布局为:
- 地址0: 78h (低字节)
- 地址1: 56h
- 地址2: 34h
- 地址3: 12h (高字节)

要分解高低16位,您可以直接通过内存偏移访问:
- 低16位:从基地址取一个字(word)
- 高16位:从基地址+2取一个字

示例代码:

assume cs:code, ds:data
data segment
    num dd 12345678h   ; 定义一个32位数
    low_part dw ?      ; 存储低16位
    high_part dw ?   ; 存储高16位
data ends

code segment
start:
    mov ax, data
    mov ds, ax

    ; 从num取低16位到AX
    mov ax, word ptr    ; AX = 5678h

    ; 从num取高16位到DX
    mov dx, word ptr ; DX = 1234h

    ; 存储到变量(可选)
    mov , ax
    mov , dx

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


关键点:
- 使用 word ptr 指定内存访问大小为字(16位)。
- 偏移地址 对应低16位, 对应高16位。
- 如果您有32位十进制数(如1000000),汇编器会自动转换为十六进制,无需手动转换。

您的理解是正确的:内存是字节序列,通过偏移地址灵活访问即可。继续练习,您会掌握得更透彻!如果有具体问题,欢迎补充细节。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 汇编实验七