john_he 发表于 2007-9-11 13:54:58

汇编高手请进

请问这段代码是怎么执行的?主要是那个js什么时候会跳转……


loc_475A3C:
               mov   dl,
               mov   al,
               add   esi, 1
               movzx   ecx, al
               mov   eax, ecx
               and   eax, 0F0h
               movzx   edx, dl
               shl   eax, 4
               or      eax, edx
               and   ecx, 0Fh
               add   esi, 1
               add   ecx, 2
               mov   , ecx
               mov   edx, 0
               js      short loc_475AA5

;......


最后那个js什么时候会跳?按我的理解,应该是对上的“add ecx,2”结果为负的时候跳,可是看上面的程序觉得这没可能啊……

coolpay64 发表于 2007-9-11 18:30:29

某認為最大的問題是,js真的是指上一個Operation會修改sign嗎?
還是指edx等等的物事其中一個會影響sign值嗎?
因為某沒學過x86-32bit的ASM

lw 发表于 2007-9-11 20:34:53

不明白什么是为甚不能跳转——如果那个时候add之后还是负数不就跳了?

john_he 发表于 2007-9-11 20:46:57

某認為最大的問題是,js真的是指上一個Operation會修改sign嗎?
還是指edx等等的物事其中一個會影響sign值嗎?
因為某沒學過x86-32bit的ASM
会的,按Intel的文档,add指令会修改SF,要不标志不都没用了嘛……

不明白什么是为甚不能跳转——如果那个时候add之后还是负数不就跳了?
movzxecx, al
and ecx, 0Fh
关键是这两条指令,先零扩展了,所以ecx高24位全是0,然后还and个0Fh,所以到那时ecx最大应该就15啊,再加2,没啥可能让ecx最高位是0吧……

coolpay64 发表于 2007-9-11 21:30:46

LZ還是上載整個代碼吧。。最好有變量注解...XD
(看來某的編程還是不行呢。。。 )

john_he 发表于 2007-9-11 21:46:35

整个来是可以,不过那一段应该是相对独立,跟其他部分关系不大(应该是if的一个分支),而且是反汇编来的,注释基本没有……

Zelsazgh 发表于 2007-9-11 22:26:36

JS指令是指符号标记位为一....不一定要ADD的时候才可以....之前只要标记过了...都算...貌似是这样

rednaxela 发表于 2007-9-12 20:09:08

其实我印象中这是个编译器行为,那句JS在调试的时候应该是从来都不会有跳转成立的情况.

之前在debug另外几个游戏的时候也看到了类似的状况.在一句JMP之前有一句JS,但那句JS的跳转条件从来不成立(跟这里很类似的有做AND的mask操作).我说的情况都是在LZSS的解压函数里碰到的.于是我很好奇的看了一下自己写的LZSS解压函数编译出来的结果,果然也有这句JS.但我原本的代码里根本没这个判断的.

编译器经常会弄出些奇怪的东西.之前还见过VC6的编译器输出
add eax, 1
sub eax, 1
这样无厘头的东西.不得不怀疑这里也是这种情况.

coolpay64 发表于 2007-9-12 21:44:47

反汇编...會不會反錯了。。。
既是如此,JS永遠不會有成立之時,那是不是偵錯mode時會有效?

john_he 发表于 2007-9-14 10:53:54

引用第7楼rednaxela于2007-09-12 20:09发表的:
其实我印象中这是个编译器行为,那句JS在调试的时候应该是从来都不会有跳转成立的情况.

之前在debug另外几个游戏的时候也看到了类似的状况.在一句JMP之前有一句JS,但那句JS的跳转条件从来不成立(跟这里很类似的有做AND的mask操作).我说的情况都是在LZSS的解压函数里碰到的.于是我很好奇的看了一下自己写的LZSS解压函数编译出来的结果,果然也有这句JS.但我原本的代码里根本没这个判断的.

编译器经常会弄出些奇怪的东西.之前还见过VC6的编译器输出
.......

听阁下这么一说,我有点头绪了……
这应该是编译器弄出来的,目的应该是位对齐。从那个完整代码可以看出,紧跟JS后面是个循环体,但循环体的起始地址不是4字节对齐,对性能会有影响。JS short机器码是2字节,不跳转时CPU周期为1,比用两个NOP(每个CPU周期为1)要好,因此用来占位,占位后的地址.text:00475A70就16字节对齐了。

add eax, 1
sub eax, 1
是典型的占位用法,占5+5=10字节,CPU周期是1+1=2。
还有
lea ecx, dword ptr
之类的也是占位用法。
页: [1]
查看完整版本: 汇编高手请进