注册 登录
编程论坛 汇编论坛

[休闲]如何区分程序中用到的是数据区的首地址,还是他的值

Push 发布于 2006-12-18 13:42, 1713 次点击

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;输入一字符串,转化成小写字母后输出
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DATA SEGMENT
str DB 100 ;缓冲区最大字符
DB ? ;实际输入字符数
DB 100 DUP(0) ;分配100个内存单元
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,SEG str
MOV DS,AX
MOV AH,0AH
LEA DX,str
INT 21H ;调用DOS10号功能输入字符串
MOV SI,DX
ADC SI,02H
MOV CX,64H ;循环100次
COMPA: MOV AL,[SI]
CMP AL,00H
JE NEXT ;如果下一个内存单元是默认值,就退出循环
CMP AL,41H
JL L1
CMP AL,5AH
JG L1 ;判断字符是否大写字母(ASCII码是否在41H-5AH间(65-90))
ADD [SI],20H ;如果是就加上32,变成写字母
L1: INC SI
LOOP COMPA ;跳到下一个字符
NEXT: MOV DL,0DH
MOV AH,02H
INT 21H
MOV DL,0AH
MOV AH,02H
INT 21H ;输出回车换行

MOV AH,40H
MOV DX,offset str+02H ;字符起始地址,要+2,是因为用10号功能输入时前两个是系统使用的
MOV CX,00H
MOV SI,offset str+01H
MOV CL,[SI] ;字符长度
MOV BX,01H
INT 21H ;调用DOS40H功能输出字符串
MOV AH,4CH
INT 21H
CODE ENDS
END START

[此贴子已经被作者于2006-12-19 11:57:01编辑过]

17 回复
#2
lefttime2006-12-18 15:28

我也来一个例子:
DSEG SGEMENT
NOTE0 DB 0AH,0DH,'Input strings : $'
NOTE1 DB 0AH,0DH,'New strings : $'
TEMP DB 100,0,100 DUP('$') ;我个人觉得这里分不分段写无所谓 ^ ^
DSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DSEG
MAIN: MOV AX,DSEG
MOV DS,AX
MOV AH,9
LEA DX,NOTE0
MOV AH,10
LEA DX,TEMP
INT 21H
LEA BX,TEMP+1
MOV CX,[BX]
NEXT: INC BX
CMP BYTE PTR [BX],24H ;先判断字符串是否结束
JZ OUTPUT
CMP BYTE PTR [BX],41H ;这里开始判断是否为大写字母
JL NEXT
CMP BYTE PTR [BX],5AH
JG NEXT
ADD BYTE PTR [BX],20H ;大写字母转为小写字母,楼主的有句话写错了呀 加上32是
转小写而不是大写
JMP NEXT ;因为前面已经有判断结束,所以这里强制转移,以便循环判断
OUTPUT: MOV AH,9
LEA DX,NOTE1
INT 21H
LEA DX,TEMP+2
INT 21H
MOV AX,4C00H
INT 21H
CSEG ENDS
END MAIN

#3
Push2006-12-18 17:53
谢谢楼上的大哥
我问个问题哈
LEA DX,TEMP+2
这一句,TEMP是个标号,为什么可以不用offset temp,而直接用TEMP+2呢
我的理解是直接用TEMP表示TEMP标号第一个字符的值0,
而你们的是偏移地址

这是怎么回事呢
比如
X DB 2
Y DB 3
直接用X,Y就表示其值呀,这个没有歧义
为什么
XY DB 2,3,4
这时XY就表示偏移地址了呢?

怎么区分他们?
#4
lefttime2006-12-18 18:37
记得上次有个会员问过变量与标号的区别,我已经说过了; 在这里TEMP是个变量,而不是标号,我比较喜欢称它为变量吧但实质上它是一个常量,就像我们C语言中:
......
int temp=1;
......
这里的temp同样说成变量,但它定义的同时已经初始化了值!
数据段中的定义变量代表可以区分每个数据的同时还是它所指示数据区的首地址,直说了它就是一个地址
所以TEMP+2就是 100 DUP(?) 的第一个字符的地址.
offset temp 是个好方法,它属于一种静态取偏移量,但是它局限于取一个数据 (注意不是数据段)的首地址,遇到上面取第二个字符的地址时不太合适了.

这样下来应该明白
X DB 2
Y DB 3
中X、Y的含义了吧
#5
Push2006-12-18 19:10
有点明白了
offset是取的一个数据区的首地址
比如temp db 1,2,3,4
这里取的是1,2,3,4这个数据区的首地址,就是第一个数1的地址

int temp=1;
......
这里的temp同样说成变量,但它定义的同时已经初始化了值!

对上面这种情况,它既代表了数据区的首地址,但又代表一个值,如上面的值1.

这样,在程序中如何区分是用到它的地址还是它的值呢
这点我还不明白呢
#6
lefttime2006-12-19 12:33
我们直接用它,就是取该变量指向的单元内容
......
MOV AL,TEMP ;AL中的内容就是TEMP指向的内容
......
;而下面三条就是取地址啦
LEA BX,TEMP ;这条和下面一条效果一样,取偏移量地址
MOV BX, OFFSET TEMP
MOV BX, REG TEMP ;这条是取该变量所在的段基址,非常实用
......
#7
Push2006-12-19 13:49
谢了,总算明白了
MOV BX,SEG TEMP
这个才是取段地址吧
#8
lefttime2006-12-19 16:09
呵呵, 犯了个小错误不好意思
#9
Push2006-12-19 19:34
我现在明白了
我用DEBUG -T单步执行调试程序时看代码:
MOV AX,TEMP
MOV AX,TEMP+2
实际上TEMP是一个地址,用MOV时表示把这个地址里的数据放到AX中
TEMP+2是TEMP的地址加2后,形成的新地址
取的是地址指向的值
MOV AX,OFFSET TEMP+2
OFFSET TEMP是取偏移地址,+2后送到AX中,这里是送的地址,而不是地址把指向的值
LEA AX,TEMP+2
先把后面的地址算出来,再把地址送入AX
#10
菜鸟上路2006-12-20 17:33
我对这个问题也不太明白

mov ax,offset temp+2中的2应该是偏移量,那mov ax,temp+2中的2是偏移量还是实际的值

或者填下下面语句的注释

假设temp的地址是1234h,temp的值是5678h

mov ax,temp ;ax=?
mov ax,temp+2 ;ax=?
mov ax,offset temp ;ax=?
mov ax,offset temp+2 ;ax=?
lea ax,temp ;ax=?
lea ax,temp+2 ;ax=?


#11
lefttime2006-12-20 20:08

纠正10楼的一个错误,temp在内存中不存在存放单元,他只是一个名称,所以 temp的地址是1234h 这句话是错的
只能说是:
假设temp指向的地址是1234h,而偏移量为1234h开始存放的数据为5678h

#12
菜鸟上路2006-12-20 21:48
以下是引用lefttime在2006-12-20 20:08:27的发言:

纠正10楼的一个错误,temp在内存中不存在存放单元,他只是一个名称,所以 temp的地址是1234h 这句话是错的
只能说是:
假设temp指向的地址是1234h,而偏移量为1234h开始存放的数据为5678h

谢谢了,但是能注释下10楼的AX结果吗?谢谢

#13
lefttime2006-12-21 15:24
mov ax,temp ;ax=?
mov ax,temp+2 ;ax=?
mov ax,offset temp ;ax=?
mov ax,offset temp+2 ;ax=?
lea ax,temp ;ax=?
lea ax,temp+2 ;ax=?
#14
lefttime2006-12-21 15:27
如果只是
假设temp指向的地址是1234h,而偏移量为1234h开始存放的数据为5678h
那么:
mov ax,temp ;ax=7856h
mov ax,temp+2 ;ax=? 这个没给出,所以不知道
mov ax,offset temp ;ax=1234h
mov ax,offset temp+2 ;ax=1236h
lea ax,temp ;ax=1234h
lea ax,tem+2 ;ax=1236h
#15
菜鸟上路2006-12-21 16:04
以下是引用lefttime在2006-12-21 15:27:12的发言:
如果只是
假设temp指向的地址是1234h,而偏移量为1234h开始存放的数据为5678h
那么:
mov ax,temp ;ax=7856h
mov ax,temp+2 ;ax=? 这个没给出,所以不知道
mov ax,offset temp ;ax=1234h
mov ax,offset temp+2 ;ax=1236h
lea ax,temp ;ax=1234h
lea ax,tem+2 ;ax=1236h

谢谢!
mov ax,temp+2 ;ax不是等于5678h+2吗?

#16
lefttime2006-12-21 16:13
[QUOTE]mov ax,temp+2 ;ax不是等于5678h+2吗?[/QUOTE]
流汗中......
前面的东东白说了!
#17
jmasm2006-12-23 19:26

ax=[5678H+2]

#18
菜鸟上路2006-12-23 22:21
以下是引用jmasm在2006-12-23 19:26:21的发言:

ax=[5678H+2]


谢谢,已经明白了

1