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

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

2009-9-5 15:16
1188
大家好,我看罗云彬的那本《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
这是怎么一回事呢,苦思冥想不得其解,望大家指教!!

[2023春季班]《安卓高级研修班(网课)》月薪两万班招生中~

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

---我怀疑是不是负数的缘故呢??
雪    币: 251
活跃值: 活跃值 (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
leftup 活跃值 2009-9-5 23:38
5
0
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
雪    币: 100
活跃值: 活跃值 (23)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
hearmecryle 活跃值 1 2009-9-6 00:31
6
0
具体原理不清楚,装上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"
只说返值是真或其它值.还是不得要领.

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