【原创】WIN32汇编初学者经常问的两个问题 其实是看书不专心造成的啊。。
;*************************************************************************;By zklhp
;Email:zklhp#(#==@) QQ:493165744
;版权所有 转载请保持完整
;*************************************************************************
我不讲 只复制书上的
第一个 16位汇编书上的 有些人看的书上确实是没有 不过看看就明白了
相对基址加变址寻址方式有多种等价的书写方式,下面的书写格式都是正确的,并且其寻址含义也是一致的。
MOV AX, [BX+SI+1000H] MOV AX, 1000H[BX+SI]
MOV AX, 1000H[BX][SI] MOV AX, 1000H[SI][BX]
但书写格式BX [1000+SI]和SI[1000H+BX]等是错误的,即所用寄存器不能在“[“,”]”之外,该限制对寄存器相对寻址方式的书写也同样起作用。
MOV AX, [BX+SI+1000H] MOV AX, 1000H[BX+SI]
MOV AX, 1000H[BX][SI] MOV AX, 1000H[SI][BX]
但书写格式BX [1000+SI]和SI[1000H+BX]等是错误的,即所用寄存器不能在“[“,”]”之外,该限制对寄存器相对寻址方式的书写也同样起作用。
于是 你们问的什么mov eax,1234[esi] 一类是什么意思都明确了罢
更深入一点 32位的内存寻址其实是这么个格式
段:[寄存器+寄存器*n+立即数]
其中n=1 2 4 8 第一个寄存器叫 基址寄存器 第二个叫变址寄存器 其实就是 除了ESP不能做变址寄存器 其余寄存器都可以用
书上如是说
32位基址寄存器是:EAX、EBX、ECX、EDX、ESI、EDI、EBP和ESP;
32位变址寄存器是:EAX、EBX、ECX、EDX、ESI、EDI和EBP(除ESP之外)。
32位变址寄存器是:EAX、EBX、ECX、EDX、ESI、EDI和EBP(除ESP之外)。
下面也是
由于32位寻址方式能使用所有的通用寄存器,所以,和该有效地址相组合的段寄存器也就有新的规定。具体规定如下:
1、地址中寄存器的书写顺序决定该寄存器是基址寄存器,还是变址寄存器;
2、默认段寄存器的选用取决于基址寄存器;
3、基址寄存器是EBP或ESP时,默认的段寄存器是SS,否则,默认的段寄存器是DS;
4、在指令中,如果使用段前缀的方式,那么,显式段寄存器优先。
1、地址中寄存器的书写顺序决定该寄存器是基址寄存器,还是变址寄存器;
2、默认段寄存器的选用取决于基址寄存器;
3、基址寄存器是EBP或ESP时,默认的段寄存器是SS,否则,默认的段寄存器是DS;
4、在指令中,如果使用段前缀的方式,那么,显式段寄存器优先。
由于win32汇编用的平坦模式 讨论这个其实没意思 知道就好了
更深入的可以看下Intel的指令手册
@@ @F @B ???
以下罗大的书
在DOS时代,为标号起名是个麻烦的事情,因为汇编指令用到跳转指令特别多,任何比较和测试等都要涉及跳转,所以在程序中会有很多标号,在整个程序范围内起个不重名的标号要费一番功夫,结果常常用addr1和addr2之类的标号一直延续下去,如果后来要在中间插一个标号,那么就常常出现addr1_1和loop10_5之类奇怪的标号。
实际上,很多标号只会使用一到两次,而且不一定非要起个有意义的名称,如汇编程序中下列代码结构很多:
mov cx,1234h
cmp flag,1
jz loc1
mov cx,1000h
loc1:
…
loop loc1
loc1在别的地方就再也用不到了,对于这种情况,高版本的MASM用@@标号去代替它:
mov cx,1234h
cmp flag,1
jz @F
mov cx,1000h
@@:
…
loop @B
当用@@做标号时,可以用@F和@B来引用它,@F表示本条指令后的第一个@@标号,@B表示本条指令前的第一个@@标号,程序中可以有多个@@标号,@B和@F只寻找匹配最近的一个。
不要在间隔太远的代码中使用@@标号,因为在以后的修改中@@和@B,@F中间可能会被无意中插入一个新的@@,这样一来,@B或@F就会引用到错误的地方去,源程序中@@标号和跳转指令之间的距离最好限制在编辑器能够显示的同一屏幕的范围内。
实际上,很多标号只会使用一到两次,而且不一定非要起个有意义的名称,如汇编程序中下列代码结构很多:
mov cx,1234h
cmp flag,1
jz loc1
mov cx,1000h
loc1:
…
loop loc1
loc1在别的地方就再也用不到了,对于这种情况,高版本的MASM用@@标号去代替它:
mov cx,1234h
cmp flag,1
jz @F
mov cx,1000h
@@:
…
loop @B
当用@@做标号时,可以用@F和@B来引用它,@F表示本条指令后的第一个@@标号,@B表示本条指令前的第一个@@标号,程序中可以有多个@@标号,@B和@F只寻找匹配最近的一个。
不要在间隔太远的代码中使用@@标号,因为在以后的修改中@@和@B,@F中间可能会被无意中插入一个新的@@,这样一来,@B或@F就会引用到错误的地方去,源程序中@@标号和跳转指令之间的距离最好限制在编辑器能够显示的同一屏幕的范围内。
[ 本帖最后由 zklhp 于 2011-5-22 21:48 编辑 ]