能力值:
( LV3,RANK:20 )
2 楼
[2]和2肯定不一样,2是立即数,【2】是相对于data段偏移为2的地址取数据,数据大小是dword
能力值:
( LV2,RANK:10 )
3 楼
2楼说得对!楼主可能是没有理解“[xxx]”中的方括号的用途了。王爽先生的《汇编语言》第46页“3.2 DS和[address]”就讨论了这个问题。书中写到:“[... ]”表示一个内存单元,“[...]”中的0(原书中的例子是0)表示内存单元的偏移地址。
能力值:
( LV2,RANK:10 )
4 楼
楼上的同学!没看出来吗?我说的是不一样!!理论结果应该是一样的啊!!就是说后面两条语句执行的结果不一样!!
能力值:
( LV2,RANK:10 )
5 楼
你如果直接写mov ax,[2]的话确实是将2放入ax,跟mov ax,2是一样的,如果你想用间接寻址的话应该这么写:mov ax,ds:[2],这样编译出来的就是你想要的了。
默认传送一个WORD,不是DWORD。
能力值:
( LV9,RANK:170 )
6 楼
mov ax, [2] 和 mov ax, 2 不可能一样的,前面是内存操作数,后者是立即数
lea ax, [2] 和 mov ax, 2 结果就是一样
可能有些反汇编器显示为 mov ax, ds:2 让你觉得和 mov ax, 2 是一样的
能力值:
( LV2,RANK:10 )
7 楼
Mov bx,2
Mov ax,[bx]
================
mov ax,[2]
这两个都是默认使用ds做默认的段前缀,怎么可能效果不一样呢.机器码不同,但是效果还是一样的
能力值:
( LV2,RANK:10 )
8 楼
先不说反汇编结果如何,你们有试过吗???你自己用Masm试试?再用Debug来观察执行过程!看Ax里的值的变化
能力值:
( 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
-
能力值:
( LV2,RANK:10 )
10 楼
努力学习中那个。。
能力值:
( 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]
结论是 你没用过内联汇编
能力值:
( LV2,RANK:10 )
12 楼
9楼!!你说这是为什么呢??
能力值:
( LV9,RANK:170 )
13 楼
汗,你也太武断了,不知道你怎样得出这个结论的
淡定点,仔细想想,这是我对你的忠告
能力值:
( 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.
如果你这样认为是一样的,我就无语了
能力值:
( LV2,RANK:10 )
15 楼
是你自己没看清楚吧!9L的确说的是对的啊
你没看到有一共有3个关于mov ax,2的吗?
前面2个都是b80200.只有后面一个加了ds的才是a10200的啊!!
能力值:
( LV9,RANK:170 )
16 楼
汗!还真是这样,是我没看清楚!和 9L 的朋友说声对不起
但,那应该是masm的错,这不是良好编译器的行为
能力值:
( LV2,RANK:10 )
17 楼
我只能猜测一下原因了,如果直接写mov ax,[2]的话,Masm认为你是不小心写错了,所以“悄悄地”帮你纠正了……而如果写mov ax,ds:[2]就可以确定你确实是想直接使用这个地址,所以就出现了这种情况。
或者是当初写编译器的时候犯了一个低级错误?
总之不管如何,我认为至少要给出一个警告信息的(如果不是编译器bug的话),类似mik所说的,这绝不是一个良好的编译器应有的行为。
能力值:
( LV6,RANK:80 )
18 楼
你自己内联个汇编试试 就知道你年轻成什么样了
内联汇编里面立即数加[]和不加一个样 你没编过程序吧?
能力值:
( 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其实是一样的。但是蛋疼的汇编器写出来之后,前端扫描的时候,把所有这样的情况都认为可以等价,导致现在在内联中部分直接寻址被匹配成立即寻址。
能力值:
( LV2,RANK:10 )
20 楼
不同的高级编译器编译的结果有时不一样,看编译器怎么理解了。
能力值:
( 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对指令的不同处理"
能力值:
( LV2,RANK:10 )
22 楼
这个帖子,知道了不少东西,谢谢楼主的发现,也谢谢牛人的解释~!