. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->数据处理的两个基本问题
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  花了14小时多!第八章实验7 答案和方法公布!  [待解决] 回复[ 5次 ]   点击[ 495次 ]  
zhenglxd
[帖 主]   [ 发表时间:2009-05-08 20:50 ]   [引用]   [回复]   [ top ] 
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05
assume cs:codesg ,ds:data,ss:stack,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,2795000,3753000,4649000,5937000 
dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226 
dw 11542,14430,15257,17800 
data ends 

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

stack segment 
dw 16 dup(0) 
stack ends 

codesg segment 
start:  mov ax,data
        mov ds,ax
        mov ax,stack
        mov ss,ax
        mov sp,16
        mov ax,table
        mov es,ax
        mov bx,0
        mov di,0
        mov si,168
        mov cx,21
s0:     mov bp,cx
        mov cx,2
      s:push ds:[di]
        pop es:[bx]
        push ds:[di+2]
        pop es:[bx+2]
        add di,84
        add bx,5
        loop s
        push ds:[si]
        pop es:[bx]
        mov ax,es:[bx-5]
        mov dx,es:[bx-3]
        div word ptr ds:[si]
        mov es:[bx+3],ax
        add bx,6
        add si,2
        sub di,164
        mov cx,bp
        loop s0
        
        mov ax,4c00H
        int 21H
codesg ends
end start
        
花了14小时走了许多弯路不过最终还是被攻克了!用的都是前面学到范围内的知识!这里想和大家说下心得,代码越简单未必越好,出于维护的目的越易懂越清晰为佳!曾经想过许多用栈的方案最后不是失败就是搁浅,这个方法其实还蛮幼稚的,但是 他容易被人接受,因为思路很简单

按照整体而言 这个题难无非有2  
1是怎么 从data段取出你需要的数据 
2是怎么按顺序的送回es段(我设置的)

上题中我用了个栈来做 中转

用bx 来定位es中的 基础地质从0开始,每循环一次 bx起点地址+16  用来实现 行的循环
用di 来定位ds段的基础地址从0开始,用[idata]来进行跳跃寻址,一个整体循环后,实际增长4


本题有个蛮讨厌地方就是 雇员数 他实际是word单元 所以我为他专门用了个变量定位地址
相信很多人不注意这个 他实际是字单元所以不能和上面用同一变量

希望对大家有帮助!
jhchen002
[第1楼]   [ 回复时间:2009-05-11 22:30 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-05-04 20:45
写的蛮好的,比我写的好。使用了栈达到了年份和收入的复制,这样使程序很简洁。我在使用段前缀的时候出了些问题。例如:mov ds:[bp+5], ax,虽然强制使用了段前缀,但bp还是默认要使用ss,这个很讨厌,看你这个程序段前缀运行的蛮好的,我的上面怎么就不行了。

顺便问一下:前面assume有什么作用,不使用感觉也没什么错。
zhenglxd
[第2楼]   [ 回复时间:2009-05-12 09:04 ]   [引用]   [回复]   [ top ] 
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05
assume是假设的意思  你假设 你自定义的段和某个寄存器有联系 这样 在写代码的时候 可以直接 把段名(地址)赋给寄存器 然后再付给相关的段寄存器 不然的话 类似 data的这样的段名 就无法作为地址 直接被使用 比如说 mov ax,data 你如果不把data和任何一个 寄存器做联系 那么 你无法把它的地址直接 赋予给 ax  

我使用栈 仅仅是用于交换单一数据 这样的目的是可以少写几行代码 保证整洁度 另外用栈可以一次处理多个数据 这样可以减少代码的长度 和循环数 但是看的人要理解起来 比较烦 应为这题的地址是跳跃式的
zhenglxd
[第3楼]   [ 回复时间:2009-05-12 09:06 ]   [引用]   [回复]   [ top ] 
荣誉值:30
信誉值:0
注册日期:2009-04-09 10:05
回复:[第1楼]
------------------
bp默认的是 ss
如果想把仅做便宜地址使用 要用 段寄存器:偏移地址形式 类似 ds:[bp] 他仅仅是在不指示段寄存器的情况下 默认为ss而已 和[bx]默认为ds的原理一样
jhchen002
[第4楼]   [ 回复时间:2009-05-12 22:08 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-05-04 20:45
assume是假设的意思  你假设 你自定义的段和某个寄存器有联系 这样 在写代码的时候 可以直接 把段名(地址)赋给寄存器 然后再付给相关的段寄存器 不然的话 类似 data的这样的段名 就无法作为地址 直接被使用 比如说 mov ax,data 你如果不把data和任何一个 寄存器做联系 那么 你无法把它的地址直接 赋予给 ax  

我使用栈 仅仅是用于交换单一数据 这样的目的是可以少写几行代码 保证整洁度 另外用栈可以一次处理多个数据 这样可以减少代码的长度 和循环数 但是看的人要理解起来 比较烦 应为这题的地址是跳跃式的
------------------
回复:不使用assume是可以的,你可以实验一下。把你的代码只assume cs:codesg ,其余不用假定,你可以实验一下。
hswad
[第5楼]   [ 回复时间:2009-05-14 12:17 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-05-11 15:51
lz把cx送到bp啊,bp功能和bx相似,默认段地址为ss.书上说:临时数据的存放用栈。

我的检查下
---------------------------------------------------------
assume cs:codesg,ds:data,es:table,ss:stack

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 

stack segment
db 16 dup(0)
stack ends

codesg segment
start:

mov ax,data
mov ds,ax    
mov ax,table
mov es,ax
mov ax,stack
mov ss,ax
mov sp,16

mov bx,0
mov di,0
mov bp,0   ;目标数据table的起始地址,每次循环加16

mov cx,21 ;循环次数的选择以目的为主,主要目的是写出有21次循环的数据


s0:
push cx      ;书上说临时数据存放要用栈
mov si,0
mov cx,4

s:

mov al,ds:[bx+si]      ;年份为4字节,定义一个加4的变量bx
mov es:[bp+si],al
inc si
loop s

mov si,0      ;可以不要,主要是想清0

mov byte ptr es:[bp+4h],20h  ;空格

mov ax,ds:[bx+54h]   ;复制收入前2个字节,年份为4字节,定义一个加4的变量bx
mov es:[bp+5h],ax
mov ax,ds:[bx+54h+2] ;复制收入后2个字节
mov es:[bp+7h],ax    ;写入到table对应位置

mov byte ptr es:[bp+9h],20h

mov ax,ds:[di+0a8h]  ;复制员工人数,员工为2字节,定义一个加2的变量
mov es:[bp+0ah],ax

mov byte ptr es:[bp+0ch],20h

mov ax,es:[bp+5h]
mov dx,es:[bp+7h]
div word ptr es:[bp+0ah]   ;计算人均收入
mov es:[bp+0dh],ax

mov byte ptr es:[bp+0fh], 20h

add bx,4
add di,2
add bp,16

pop cx    ;恢复每次循环的cx的值

loop s0

mov ax,4c00h
int 21h

codesg ends
end start
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved