鱼C论坛

 找回密码
 立即注册
查看: 2759|回复: 13

[技术交流] 小感悟分享,for fresh men as me

[复制链接]
发表于 2012-2-18 01:18:37 | 显示全部楼层 |阅读模式

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

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

x
assume cs:code,ds:data
data segment
db 'unIX'
db 'foRR'
data ends
code segment
abcde:  mov al,'a'
mov bl,'b'
mov ax,4c00h
int 21h
code ends
end abcde
这是课本7.1的程序,通过debug编译执行后,查看data段中的值,发现'unIX'和'foRR'的值是在data段中从地址0到地址7依次存放的。从此处,我理解到:不管段中你加了多少行db…、dw…,改段所占的实际内存空间是按段中数据实际的字节总数N来判断的,与定义了多少行的db…、dw…没有关系


                               
登录/注册后可看大图
该贴已经同步到 风剑河的微博
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-18 01:57:53 | 显示全部楼层
2. 在做7.7章问题7.2的时候我将程序写成了如下形式
assume cs:codesg,ds:datasg
datasg segment
db 'welcome to masm!'
db '................'
datasg ends
codesg segment
start:
      mov ax,datasg
      mov ds,ax
      mov si,0
      mov di,16
      mov cx,16
          s:
            mov [di],[si]                inc di
                inc si
                loop s
codesg ends
end start
编译时出现错误,错误在于mov指令的使用错误,mov、add、sub课本中列出了好多种使用形式,我也没去死记,于是就出现这个错误,回头上课本中一查,没有内存单元赋值给内存单元的形式……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-18 02:05:09 | 显示全部楼层
3. 还是上面那题,由于我对dw定义字型数据、db定义字节型数据映像比较深,所以在碰到db定义的数据时,我总是按字节进行处理,其实对于复制来说,能一次复制两个字节我为什么还要一个一个复制呢?所以按字型数据来处理会好得多
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-2-18 08:18:48 | 显示全部楼层
这是你的学习笔记吗    很好   值得分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-2-18 08:23:25 | 显示全部楼层
记得印象最深的就是没有内存单元到内存单元的转移……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-18 17:24:16 | 显示全部楼层
4.在写问题7.6程序的时候,由于需要将第一个字母进行按位与运算,我将程序写成了“and 3[bx],11011111”,编译时出现错误,书上和甲鱼大大的视频上都是先将[bx+3]赋值给al,然后对al进行按位与运算。看来是不能直接对内存单元进行按位与或运算,前面还验证了add、mov、sub指令不能用内存单元对内存单元的形式进行。
那么为什么不行呢??
回忆一下内存单元、回忆一下寄存器,当然仅仅是回忆是不够的,直接翻书查看
寄存器是CPU的一个内部组件,CPU的内部组件还包括运算器、内部总线,控制器;内存是一个外部器件。首先,我们经常听到的是“读写内存”“CPU的运算速度”等短语,再结合书本,那就可以明确一点,CPU的运算是在CPU内部进行,在其内部的寄存器之间或寄存器与数据之间,而CPU与内存之间的关系就是读和写,将内存中的数据读入寄存器或将寄存器的数据写入内存,概括来说就是一句话“CPU不能直接对内存单元进行运算”。回头想一下,如果CPU能直接在内存单元间进行运算的话,还要寄存器干什么??
由此我可以总结一下,凡是涉及到内存单元需要运算的情况,先将内存单元的数据读入寄存器,运算完后,再将结果写入内存单元。mov、add、sub等都既是读指令又是写指令
内存单元总是和寄存器打交道,不能和寄存器以外的东西打交道(不管隔壁的内存单元还是数据本身都不行),寄存器就是内存单元的经纪人,不管你想和内存妹妹干什么,都得通过寄存器!
这是我个人总结思考出来的,大家觉得有问题的地方请指出来,这样才能相互进步,也希望高手们帮忙指导指导,可别冷眼看我走入误区呀:P
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-2-18 18:12:33 | 显示全部楼层
有两个操作数的指令,必然有一个是寄存器
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-20 22:00:35 | 显示全部楼层
经过好几个小时的奋斗,经历了从写程序、到编译、到debug,一步一步的出现错误、查找原因、修改错误的过程,实验七终于攻克了!!:lol:lol:lol:lol:lol
以下为俺的程序:
assume cs:code,ds:data
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,15257,17800

data ends

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

code segment
start:
mov ax,data
mov ds,ax
mov ax,table
mov es,ax
mov bx,0
mov di,0
mov cx,21
mov si,0
s0:
mov ds:[0d4h],cx
mov cx,[si].168 ;雇员
mov es:[bx].0ah,cx

mov ax,[di].84   ;收入  注意双字型数据的存放方式
mov es:[bx].5,ax
mov dx,[di].86
mov es:[bx].7,dx

div cx          ;人均
mov es:[bx].0dh,ax
mov ax,[di].0   ;年份
mov es:[bx].0,ax
mov ax,[di].2
mov es:[bx].2,ax
add bx,16
add di,4
add si,2
mov cx,ds:[0d4h]
loop s0

mov ax,4c00h
int 21h

code ends

end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-25 00:54:06 | 显示全部楼层
第50课思考题分享
assume cs:code,ds:data
data segment
dw 1,2,3,4,5,6,7,8
dw 0,0,0,0,0,0,0,0
data ends

code segment
fjh:
     mov ax,data
         mov ds,ax
         mov cx,8
         mov bx,0
s:   
     mov al,[bx]
         call s1
         mov 10h[bx],ax
         add bx,2
         loop s
         
         mov ax,4c00h
         int 21h         
         
s1:
         mov dl,al
         mul dl
         mul dl
         ret
         

         
code ends
end fjh         
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-25 10:59:07 | 显示全部楼层
试验10,问题1通过
assume cs:code
data segment
db 'Welcome to masm!',0
data ends

code segment
start:   mov dh,12
         mov dl,16
                 mov cl,01111100b
                 mov ax,data
                 mov ds,ax
                 mov si,0
                 call show_str  ;已用dx,cl,
                 
                 mov ax,4c00h
                 int 21h
                 
show_str:
                 ;初始化
                 mov bl,cl        ;转移设置颜色寄存器
                 mov ax,0b800h
                 mov es,ax      
                 mov ax,0
                 mov ch,0
                 mov cl,dh       
                 
        s:         add ax,160
                 loop s
                 
                 mov cl,dl
                 dec cl
        s0:         add ax,2
                 loop s0
                 
                 mov bp,ax
                                  
                 ;运算   需要显存地址,字符串地址,颜色寄存器
        s1:         
             mov di,si       
                 add di,si         ;设置显存地址变量,2*si
                 mov cl,[si]
                 jcxz s2                 
                 mov es:[bp+di],cl  ;此处赋值出现错误,全为0
                 mov es:[bp+di+1],bl
                 
                 
                 ;返回 
                 
                 
                 
                 ;循环  需要CX
                 inc si
                 jmp s1
        s2:  ret             ;此处返回出现错误地址 此处用到栈,而前面将显存空间设为了栈空间,这就容易出现错误。
                 
                 


code ends
end start                 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-2-25 12:18:06 | 显示全部楼层
试验10,问题2
编译过程中出现了error A4910:cannot open file: E:\try\ML.err
不知道各位兄弟姐妹有出现这样错误的没??
上百度查,说是ML.err文件被杀毒软件误删了?但我编译别的程序没问题,于我是就找程序的原因。
原来我不知发什么疯,把divdw子程序放到code ends/end start后面了,将子程序放入code段中后编译链接无问题。
assume cs:code
code segment
start: 
     mov ax,4240h
         mov dx,000fh
         mov cx,0ah
         call divdw
         
         mov ax,4c00h
         int 21h
         
         
         divdw:
     push ax      ;被除数低位入栈4240h
         mov ax,dx          ;被除数高位放入ax中 
     mov dx,0         ;将高位清零
         div cx      ;对被除数高位进行除法运算
         pop bx      ;从栈中取出被除数的低位
         push ax     ;将高位除法的商入栈
         mov ax,bx   ;将低位被除数放入ax中
         div cx      ;对总余数进行除法运算
         mov cx,dx   ;将最终余数放入cx
         pop dx      ;将高位除法的商放入dx 
         ret
         
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2012-3-2 10:39:11 | 显示全部楼层
监测点11.2,
在做mov al,0fch    add al,05h的时候让我迷惑了一下,不知道有没有也在此迷惑的同学。我在此分享一下。
Mov al,0fch               al=11111100
                         +00000101
Add al,05h       al=al+05h=1 00000001
此时的OF标志位是什么呢?刚开始的时候,我认为是1,因为它从最高位溢出了,但答案却是0。刚开始我还怎么都想不明白,蹲厕所时还想呢,突然就想到OF标志位的对象是有符号数,对于字节来说有符号数的运算其溢出好像是指由第7位向第8位进位,而且判断的时候要先将两个相加的数看做有符号数来判断才更清晰。于是我就分析了一下,0fch所表示的有符号数是十进制的-4,而05h的有符号数是十进制的5,他们相加得十进制的1,换为二进制就是00000001,其符号位就是0,也就是说这两个数的有符号运算向符号位的进位没有影响有符号运算结果,所以就没有溢出,OF应该为0

我觉得好像是越说越糊涂了,翻书一查,确实乱。书上说了,若要当成有符号数计算,先把两个数换成十进制的有符号数,相加以后,看结果是不是在-128~127范围内,是的话就无溢出,不是的话就有溢出。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-3-2 17:25:18 | 显示全部楼层
值得学习,自己的汇编能力现在还差的远呢,要加油了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-3-3 01:13:59 | 显示全部楼层
厉害,我还没有学到这一步呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-19 20:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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