ZERO? 在Win32汇编中问题??

okmnji79513 2010-03-29 06:12:43
罗云彬 的 Win环境下32位汇编语言程序设计 中 附录B中,
有如下一段子程序:

;_ShowMessage子程序用来将消息查表翻译成字符串,源程序如下:
_ShowMessage proc _uMsg,_wParam,_lParam
local @szBuffer[128]:byte

pushad
;********************************************************************
; 查找消息的说明字符串
;********************************************************************
mov eax,_uMsg
mov edi,offset dwMsgTable
mov ecx,MSG_TABLE_LEN
cld
repnz scasd
.if ZERO?
sub edi,offset dwMsgTable + sizeof dword
shr edi,2
mov eax,edi
mov ecx,MSG_STRING_LEN
mul ecx
add eax,offset szStringTable
;********************************************************************
; 翻译格式并发送到 Notepad 窗口
;********************************************************************
invoke wsprintf,addr @szBuffer,addr szFormat,\
_uMsg,eax,_wParam,_lParam
invoke _SendtoNotepad,addr @szBuffer
.endif
popad
ret

_ShowMessage endp

下面是说明文字的一部分:
“在这里要用到repnz scasd指令,scasd指令是把eax中的值从[edi]开始的内存中按双字比较,同时将edi加4,如果相等,则ZR标志置位,否则为NZ,repnz表示如果标志为NZ,则以ecx为重复次数重复搜索,直到相等或ecx为零为止。
将ecx赋值为消息表的项数MSG_TABLE_LEN,将edi赋值为消息表的开始地址offset dwMsgTable,然后开始查找,停止后可以查看标志Zero位,如果是非ZERO,表示查完全部都没有找到,如果是ZERO,则表示找到表项


如上 , 是否应该是 : "如果是ZERO,表示查完全部都没有找到,如果是 非 ZERO,则表示找到表项" 搞反掉了???

还有 ,每次进入 _ShowMessage子程序 时 ZERO 都 自动 是0吗??还是哪里设置了??(没看出来哪里有设置ZERO为0的操作)

菜鸟提问,请大家帮们解答上面3个问题,谢谢。
...全文
296 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiangandlijie 2010-12-20
  • 打赏
  • 举报
回复
不用反汇编吧,11楼这才是合逻辑的正解。
okmnji79513 2010-03-31
  • 打赏
  • 举报
回复
哦~~ 明白了,每次循环比较后都会使ZF位为1或0 .
zara 2010-03-31
  • 打赏
  • 举报
回复
ZF 的清或是置,是由紧上面的那条 REPNE SCASD 指令根据搜索结果所动作的,不是其它的指令。
上面 #8楼 的 balckfacewa 贴出来的就是该指令的说明以及对 ZF 标记位的影响。
okmnji79513 2010-03-31
  • 打赏
  • 举报
回复
to blackfacewa
你说的我看不懂......
okmnji79513 2010-03-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 cnzdgs 的回复:]
.if (zero?)表示“如果ZF=1”。
每次进入子程序不会自动设置标志位,不过对于定义了局部变量的子程序,在程序入口处会执行sub esp,xx指令,会使ZF=0。
[/Quote]
我顶楼的代码,反汇编了一下(用的w32dasm),如下图:

子程序基本是 0040104C 到 004010A2 ;调用的话,全部exe只有一处调用了该子程序,004010B4 处,
没看到任何zf清零的操作啊,也没看到"sub esp,xx指令"啊,只有 “add esp,FFFFFF80”是给局部变量预留空间的啊。

请指教。
blackfacewa 2010-03-30
  • 打赏
  • 举报
回复
关于repnz

IF AddressSize = 16
THEN
Use CX for CountReg;
ELSE IF AddressSize = 64 and REX.W used
THEN Use RCX for CountReg; FI;
ELSE
Use ECX for CountReg;
FI;
WHILE CountReg ≠ 0
DO
Service pending interrupts (if any);
Execute associated string instruction;
CountReg ← (CountReg – 1);
IF CountReg = 0
THEN exit WHILE loop; FI;
IF (Repeat prefix is REPZ or REPE) and (ZF = 0)
or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)
THEN exit WHILE loop; FI;
OD;


ZERO? 在那里定义的?
cnzdgs 2010-03-30
  • 打赏
  • 举报
回复
.if (zero?)表示“如果ZF=1”。
每次进入子程序不会自动设置标志位,不过对于定义了局部变量的子程序,在程序入口处会执行sub esp,xx指令,会使ZF=0。
okmnji79513 2010-03-30
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 cnzdgs 的回复:]
.if (zero?)表示“如果ZF=1”。
每次进入子程序不会自动设置标志位,不过对于定义了局部变量的子程序,在程序入口处会执行sub esp,xx指令,会使ZF=0。
[/Quote]
哦~~这里是这样啊,我再反汇编看看。
okmnji79513 2010-03-30
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 cnzdgs 的回复:]
.if (zero?)表示“如果ZF=1”。
每次进入子程序不会自动设置标志位,不过对于定义了局部变量的子程序,在程序入口处会执行sub esp,xx指令,会使ZF=0。
[/Quote]
哦~~这里是这样啊,我再反汇编看看。
okmnji79513 2010-03-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 fandelei1982 的回复:]
如果是ZERO 指 ZR标志位为1,为相等。非ZERO指 ZR标志位为0,为不相等。
[/Quote]
“将ecx赋值为消息表的项数MSG_TABLE_LEN,将edi赋值为消息表的开始地址offset dwMsgTable,然后开始查找,停止后可以查看标志Zero位,如果是非ZERO,表示查完全部都没有找到,如果是ZERO,则表示找到表项。”
蓝色部分,可以写成:“如果是非ZR,表示查完全部都没有找到,如果是ZR,则表示找到表项”,对不?
ZERO=ZR?

我之前理解为:“如果是非0,表示查完全部都没有找到,如果是0,则表示找到表项”。
ZERO=0
friendly_ 2010-03-29
  • 打赏
  • 举报
回复
如果是ZERO 指 ZR标志位为1,为相等。非ZERO指 ZR标志位为0,为不相等。
okmnji79513 2010-03-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fandelei1982 的回复:]
你搞反了。比较操作是进行减操作,相等即为0。若扫描完了,标志位非0,说明是ecx为0了,扫描个数完了,但不相等。
[/Quote]
他不是说 "在这里要用到repnz scasd指令,scasd指令是把eax中的值从[edi]开始的内存中按双字比较,同时将edi加4,如果相等,则ZR标志置位,否则为NZ" ?????
friendly_ 2010-03-29
  • 打赏
  • 举报
回复
你搞反了。比较操作是进行减操作,相等即为0。若扫描完了,标志位非0,说明是ecx为0了,扫描个数完了,但不相等。

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧