首页
社区
课程
招聘
[旧帖] [求助]看罗云彬的32位汇编语言第三章有一个问题请教大家 0.00雪花
发表于: 2009-9-5 15:16 1747

[旧帖] [求助]看罗云彬的32位汇编语言第三章有一个问题请教大家 0.00雪花

2009-9-5 15:16
1747
大家好,我看罗云彬的那本《windows环境下的32位汇编语言》有一段时间了,看第三章时遇到一个小问题怎么也解决不了,向大家请教一下。
第三章刚一开始作者就给出了一个简单的小例子,显示一个消息框后就退出。源代码如下:
                .386
                .model flat,stdcall
                option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include                windows.inc
include                user32.inc
includelib        user32.lib
include                kernel32.inc
includelib        kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .data
szCaption        db        'A MessageBox !',0
szText                db        'Hello, World !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .code
start:
                invoke        MessageBox,NULL,offset szText,offset szCaption,MB_OK
                invoke        ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                end        start
我把程序稍微作了一些修改,在代码段中加了一个循环,先给ecx寄存器赋值为1,循环一次就减1,循环结束条件是ecx为0。但是这就出现问题了。程序进入了死循环,总是显示那个消息框了。
源代码如下:
                .386
                .model flat,stdcall
                option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include                windows.inc
include                user32.inc
includelib        user32.lib
include                kernel32.inc
includelib        kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .data
szCaption        db        'A MessageBox !',0
szText                db        'hello,world',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .code
start:
                mov ecx,1
                .repeat
                        dec cx
                        invoke        MessageBox,NULL,addr szText,offset szCaption,MB_OK                       
                .until ecx==0       
                invoke        ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                end        start
这是怎么一回事呢,苦思冥想不得其解,望大家指教!!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我试了一下将.until ecx==0改为.until ecx>0,就可以退出了
2009-9-5 21:27
0
雪    币: 54
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
执行这一句时,invoke  MessageBox,NULL,addr szText,offset szCaption,MB_OK   
ecx的值已改变!我这里是:7C93005D
调试一下就知道了啦。
改变了很多很多次了。。。。
2009-9-5 21:31
0
雪    币: 99
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我刚好这几天也在看书,进度跟你差不多,你看看罗云彬写了一段话
在第三章、高级语句==循环语句中
“在分支和循环的伪指令反汇编后可以发现,在使用>、>=、<和<=比较符时,MASM
的伪指令总是将比较以后的跳转指令使用为jb 和jnb 等无符号数比较跳转的指令,这就
意味着,MASM 的条件测试总是把操作数当做无符号数看待,这样,假设eax 等于1,
那么表达式(eax > -1)的值是“假”,因为-1 表示为0ffffffffh,如果当做无符号数看,
它是最大的数!如果程序中需要构造有符号数的比较分支或循环结构,那么必须另外用
jl 和jg 等有符号数比较跳转的指令来完成,使用条件测试配合分支或循环伪指令可能会
得到错误的结果!”

---我怀疑是不是负数的缘故呢??
2009-9-5 23:37
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
Functions must preserve all registers, except for eax, ecx, and edx, which can be changed across a function call, and esp, which must be updated according to the calling convention

大致意思是 eax ecx edx 是 volatile register  ,在函数中可以任意使用更改,而不需要保存和恢复
http://msdn.microsoft.com/en-us/library/cc267758.aspx
2009-9-5 23:38
0
雪    币: 133
活跃值: (113)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
具体原理不清楚,装上masm32,编译后,用OD跟了一下,
查win32API中的messagebox函数,配合windows.h
发现该函数返回值与按钮选择有关,
IDOK                                 equ 1
IDYES                                equ 6
不得要领。

继续深入,发现最终会调用内核函数RtlFreeHeap释放内存,
该内核函数返回ECX=7C93005D,与3楼一致.
去msdn查,该函数是布尔型
"Return Value:
RtlFreeHeap returns TRUE if the block was freed successfully, FALSE otherwise"
只说返值是真或其它值.还是不得要领.

期望有明白人帮助解释下原理。
2009-9-6 00:31
0
雪    币: 48
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
5楼的已经解释的很清楚了,ecx在函数中可以任意更改,同eax一样,还有个问题,
eax通常做返回值用,ecx呢?有固定用法吗?
2009-9-6 08:10
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
ecx好像在 thiscall 里作为this 指针,fastcall里作为一个参数,其他不清楚
2009-9-6 10:00
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
这个是在调用API的时候 改变了ecx的原因了。
楼主可否知道 所有的API用汇编定义的时候
uses ebx ebp edi esi
也就是说只用这是个寄存器的值在调用API的前后
是不变的,ecx是不被保护的
2009-9-6 11:06
0
雪    币: 72
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
应该是函数的每次调用修改都会修改ecx。
masm的伪指令确实是用方便,让人有点感觉像高级语言了,但是没有正宗汇编的味道了,比如堆栈的直接操作等。估计是现在程序员都变懒了,加上程序和项目的规模都在不断的扩大,对堆栈等还要程序员进行底层操作,确实很浪费时间。
但是masm的那些伪指令掩盖了一些实际的运行机制,用的时候还是小心~
2009-9-7 12:36
0
雪    币: 124
活跃值: (11)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
谢谢大家了,我也估计着是调用MessageBox函数之后ecx的值被修改所以才一直循环了。呵呵,大家一讨论我明白一些了。按九楼兄弟的说法就是调用windows提供的函数时ebx,ebp,esi,edi是不用保存的,但别的寄存器就需要保护了是吧。总之多谢大家了!
2009-9-7 19:53
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
会不会好学啊!
2009-9-8 20:49
0
雪    币: 146
活跃值: (182)
能力值: ( LV13,RANK:220 )
在线值:
发帖
回帖
粉丝
13
刚好也看到这里。。。感觉根本不用老罗介绍的编译环境,一个radasm就搞定,搞得那么麻烦。。。。
2009-9-8 21:11
0
游客
登录 | 注册 方可回帖
返回
//