首页
社区
课程
招聘
8086寻址问题!
发表于: 2011-1-17 09:29 6746

8086寻址问题!

2011-1-17 09:29
6746
Mov ax,data
Mov bx,2
Mov ax,[bx]
================
mov ax,[2]
用bx和2的效果不一样啊,用就2相当于直接把2传到ax,和书上说的不一样!我用多种编译器试过了,你们可以自己把data段里面定义一下

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (21)
雪    币: 182
活跃值: (81)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
[2]和2肯定不一样,2是立即数,【2】是相对于data段偏移为2的地址取数据,数据大小是dword
2011-1-17 10:04
0
雪    币: 24
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
2楼说得对!楼主可能是没有理解“[xxx]”中的方括号的用途了。王爽先生的《汇编语言》第46页“3.2  DS和[address]”就讨论了这个问题。书中写到:“[... ]”表示一个内存单元,“[...]”中的0(原书中的例子是0)表示内存单元的偏移地址。
2011-1-17 10:15
0
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼上的同学!没看出来吗?我说的是不一样!!理论结果应该是一样的啊!!就是说后面两条语句执行的结果不一样!!
2011-1-17 10:39
0
雪    币: 401
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
你如果直接写mov ax,[2]的话确实是将2放入ax,跟mov ax,2是一样的,如果你想用间接寻址的话应该这么写:mov ax,ds:[2],这样编译出来的就是你想要的了。
默认传送一个WORD,不是DWORD。
2011-1-17 10:41
0
雪    币: 723
活跃值: (81)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
6
mov ax, [2] 和 mov ax, 2 不可能一样的,前面是内存操作数,后者是立即数
lea ax, [2] 和 mov ax, 2 结果就是一样

可能有些反汇编器显示为 mov ax, ds:2 让你觉得和 mov ax, 2 是一样的
2011-1-17 11:26
0
雪    币: 60
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
Mov bx,2
Mov ax,[bx]
================
mov ax,[2]

这两个都是默认使用ds做默认的段前缀,怎么可能效果不一样呢.机器码不同,但是效果还是一样的
2011-1-17 13:05
0
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
先不说反汇编结果如何,你们有试过吗???你自己用Masm试试?再用Debug来观察执行过程!看Ax里的值的变化
2011-1-17 13:13
0
雪    币: 401
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
6L

我知道原则上讲是不一样的,但是你拿Masm编译一下不就知道了么?mov ax,[2]确实被编译成了mov ax,2,要写成mov ax,ds:[2]才会被编译成mov ax,[2],上截图。

.code
start:
        mov ax, @data
        mov ds, ax
        mov ax, 2
        call disp
        mov ax,[2]
        call disp
        mov ax,ds:[2]
        call disp
        .exit 0

debug反汇编结果:
C:\MASM611\BIN>debug TEST.EXE
-u
1438:0000 B83A14        MOV     AX,143A
1438:0003 8ED8          MOV     DS,AX
1438:0005 B80200        MOV     AX,0002
1438:0008 E81100        CALL    001C
1438:000B B80200        MOV     AX,0002
1438:000E E80B00        CALL    001C
1438:0011 A10200        MOV     AX,[0002]
1438:0014 E80500        CALL    001C
1438:0017 B8004C        MOV     AX,4C00
1438:001A CD21          INT     21
1438:001C 8AD0          MOV     DL,AL
1438:001E 80CA30        OR      DL,30
-
2011-1-17 13:30
0
雪    币: 81
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
努力学习中那个。。
2011-1-17 13:50
0
雪    币: 245
活跃值: (93)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
11
[QUOTE=mik;916375]mov ax, [2] 和 mov ax, 2 不可能一样的,前面是内存操作数,后者是立即数
lea ax, [2] 和 mov ax, 2 结果就是一样

可能有些反汇编器显示为 mov ax, ds:2 让你觉得和 mov ax, 2 是一样的[/QUOTE]
结论是 你没用过内联汇编
2011-1-17 14:35
0
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
9楼!!你说这是为什么呢??
2011-1-17 21:30
0
雪    币: 723
活跃值: (81)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
13
汗,你也太武断了,不知道你怎样得出这个结论的
淡定点,仔细想想,这是我对你的忠告
2011-1-17 21:31
0
雪    币: 723
活跃值: (81)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
14
[QUOTE=xiilin;916412]6L

我知道原则上讲是不一样的,但是你拿Masm编译一下不就知道了么?mov ax,[2]确实被编译成了mov ax,2,要写成mov ax,ds:[2]才会被编译成mov ax,[2],上截图。

.code
start:
        mov ax, @data
        mov ds, ax
        ...[/QUOTE]

1438:0000 B83A14        MOV     AX,143A
1438:0003 8ED8          MOV     DS,AX
1438:0005 B80200        MOV     AX,0002
1438:0008 E81100        CALL    001C
1438:000B B80200        MOV     AX,0002
1438:000E E80B00        CALL    001C
1438:0011 A10200        MOV     AX,[0002]

不知道你是怎样认为:mov ax, [2] 被编译成了 mov ax, 2 ?
一个 opcode 码是 B8 一个 opcode 是 A1

      Mnemonic                   opcode              Description
MOV AX, moffset16    A1         Move 16-bit data at a specified memory offset to the AX register.
MOV reg16, imm16     B8        Move a 16-bit immediate value into a 16-bit register.

如果你这样认为是一样的,我就无语了
2011-1-17 21:40
0
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
是你自己没看清楚吧!9L的确说的是对的啊
你没看到有一共有3个关于mov ax,2的吗?
前面2个都是b80200.只有后面一个加了ds的才是a10200的啊!!
2011-1-17 21:56
0
雪    币: 723
活跃值: (81)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
16
汗!还真是这样,是我没看清楚!和 9L 的朋友说声对不起

但,那应该是masm的错,这不是良好编译器的行为
2011-1-17 22:04
0
雪    币: 401
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
我只能猜测一下原因了,如果直接写mov ax,[2]的话,Masm认为你是不小心写错了,所以“悄悄地”帮你纠正了……而如果写mov ax,ds:[2]就可以确定你确实是想直接使用这个地址,所以就出现了这种情况。

或者是当初写编译器的时候犯了一个低级错误?

总之不管如何,我认为至少要给出一个警告信息的(如果不是编译器bug的话),类似mik所说的,这绝不是一个良好的编译器应有的行为。
2011-1-17 22:56
0
雪    币: 245
活跃值: (93)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
18
你自己内联个汇编试试 就知道你年轻成什么样了
内联汇编里面立即数加[]和不加一个样 你没编过程序吧?
2011-1-18 08:38
0
雪    币: 245
活跃值: (93)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
19
[QUOTE=xiilin;916621]我只能猜测一下原因了,如果直接写mov ax,[2]的话,Masm认为你是不小心写错了,所以“悄悄地”帮你纠正了……而如果写mov ax,ds:[2]就可以确定你确实是想直接使用这个地址,所以就出现了这种情况。

或者是当初写编译器的时候犯了一个低级错误?

总之不管如何,我认为至少要给出一...[/QUOTE]

int main()
{
	int x=0x12345678;
	_asm
	{
		mov eax,[0x12345678]
		mov eax,[x]
		mov eax,x//这三个结果是 你得到了eax=0x12345678
		//正确写法
	mov edx,x
		mov eax,[edx]
		//你可以认为是一种规范或者约束 总之对于这类直接对立即数的相对寻址操作 必须
		//先经过一个GPR
	}
	return 1;
}
我认为事实是这样的 内联汇编中,直接寻址允许用符号地址来代替数值地址,比如说mov eax,[x]和mov eax,x其实是一样的。但是蛋疼的汇编器写出来之后,前端扫描的时候,把所有这样的情况都认为可以等价,导致现在在内联中部分直接寻址被匹配成立即寻址。
2011-1-18 09:17
0
雪    币: 270
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
不同的高级编译器编译的结果有时不一样,看编译器怎么理解了。
2011-1-18 09:39
0
雪    币: 60
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
这是在debug和Masm对指令的不同处理  

在debug中
mov al,[0]
mov al,[1]
mov al,[2]

在masm中
mov al,[0]
mov al,[1]
mov al,[2]

这个你自己去在debug里面输入,和用masm编译然后debug,我暂时没有权限上传图片

debug将它解释为"[idata]"是一个内存单元,"idata"是内存单元的偏移地址;而编译器将"[idata]"解释为"idata".
这个问题可以用段前缀来解决

我记得以前见过,翻了下书,果然是这个问题

不信的话呢,你可以用搜索引擎搜索一下"debug和masm对指令的不同处理"
2011-1-19 14:29
0
雪    币: 191
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
这个帖子,知道了不少东西,谢谢楼主的发现,也谢谢牛人的解释~!
2011-1-19 14:56
0
游客
登录 | 注册 方可回帖
返回
//