各位帮忙看看,为啥运行到call WriteFile就挂了

间谍 2003-11-28 02:08:42
.386
.model flat,stdcall
option casemap:none

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;include定义
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

include e:\masm32\include\windows.inc
include e:\masm32\include\user32.inc
include e:\masm32\include\kernel32.inc
includelib e:\masm32\lib\user32.lib
includelib e:\masm32\lib\kernel32.lib

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;数据段
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.data?

array db 10000 dup(?) ;默认求(1-10000)素数
h_file dd ? ;文件句柄
buf db 100 dup(?) ;缓冲区
.data
g_count dd 10000 ;区间
g_bound dd 100 ;上界
suc_word dd 0 ;文件操作参数

.const

file_name db 'd:\\result.txt',0 ;存放结果的文件名
sz_finish db '计算完成',0
sz_format db ' %5d ',0

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;代码段
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.code

start:
pushad
;初始化 array全体元素为0

mov ecx, 0
mov al, 0
@init:
cmp ecx, g_count
jg @init_finish
mov array[ecx], al
inc ecx
jmp @init

@init_finish:

;计算过程

mov eax, 1
mov array[2], 0

@find_init:
inc eax
cmp array[eax], 1
je @find_init
cmp eax, g_bound
jg @find_finish
mov cx,1
@find_begin:
push eax
inc cx
mul cx
push ax
mov ax, dx
shl eax, 8
pop ax
cmp eax, g_count
jg @go_init
mov array[eax], 1
pop eax
jmp @find_begin
@go_init:
pop eax
jmp @find_init

@find_finish:

;写入结果
push NULL
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push NULL
push FILE_SHARE_READ
push GENERIC_WRITE
push offset file_name
call CreateFile
mov h_file, eax

mov ecx, 1
@continue:
cmp ecx, g_count
jg @finish
inc ecx
test array[ecx], 0
je @write_in
jmp @continue
@write_in:
push ecx
push offset sz_format
push offset buf
call wsprintf


push NULL
push offset suc_word
push 7
push offset buf
push h_file
运行到这附近--> call WriteFile

jmp @continue
@finish:

push h_file
call CloseHandle

popad

end start

只是一个很简单的筛选法求素数,前面的过程应该问题不大,只是输出结果的时候有些问题,请大家帮忙看看,谢谢,刚开始学汇编,有很多不懂,多多指教,也请大家多多拍砖,把我代码各个方面存在的问题都指出来。
...全文
48 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
间谍 2003-11-29
  • 打赏
  • 举报
回复
刚才又想了想,pop esi后,esi的值是 offset buf,而最后的popad,因为esi是第二个pop出来的,所以正好可以还原成为esi的值,这样虽然堆栈不平衡,却可以正常运行,我的解释对吗?
如果对,那就还剩一个问题了,就是文件名那个。请大虾们帮帮忙。
间谍 2003-11-29
  • 打赏
  • 举报
回复
另外还有这句:

file_name db 'd:\\result.txt',0 ;存放结果的文件名
file_name db 'd:\result.txt',0 ;存放结果的文件名

加一个下划线和两个下划线都可以,这是为什么?

间谍 2003-11-29
  • 打赏
  • 举报
回复
我明白了一点儿,原来wsprintf的堆栈要自己来平衡,要在call wsprintf后加add esp, 12
这样的话用ecx和esi就没有区别了,可是为什么csdsjkk在call wsprintf后加pop esi,运行也正常呢?真是搞不懂。csdsjkk或其它大虾能出来解释一下吗?
lipeijie492728 2003-11-29
  • 打赏
  • 举报
回复
@go_init:
pop eax
jmp @find_init
中 pop eax 为多余,多去了一个eax



还有CloseHandle 等子程序都没有!
紫郢剑侠 2003-11-28
  • 打赏
  • 举报
回复
@init:
cmp ecx, g_count
jg @init_finish
mov array[ecx], al
inc ecx
jmp @init


这段可以用LOOP指令或调用相关的API函数来实现。
dunkel 2003-11-28
  • 打赏
  • 举报
回复
寄存器的使用约定:
http://board.win32asmcommunity.net/showthread.php?s=&threadid=118
dunkel 2003-11-28
  • 打赏
  • 举报
回复
你出问题的不是在 WriteFile 上, 而是: 首先, 文件名的字符串定义, 你的是 c 的规则, asm 中只要一个 '\' 就可以了; 其次, 你的代码中使用了 ecx 作为自己的临时变量, 但过程中又调用了 Windows 的 API , 可是根据 WinAPI 的寄存器使用约定, ecx 是要你自己负责保存的, WinAPI 返回时有可能破坏了你原来的 ecx 中内容, 类似的还有 eax 和 edx; 最后你的程序没有 ExitProcess 的调用, 不能正常终止.
间谍 2003-11-28
  • 打赏
  • 举报
回复
为什么把ecx换成esi就正常了???
Yashmak 2003-11-28
  • 打赏
  • 举报
回复
在我的机子上执行,怎么没有问题?

结果是正确的
间谍 2003-11-28
  • 打赏
  • 举报
回复
;写入结果
push NULL
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push NULL
push FILE_SHARE_READ
push GENERIC_WRITE
push offset file_name
call CreateFile
mov h_file, eax

mov esi, 1
@continue:
cmp esi, g_count
jg @finish
inc esi
cmp array[esi], 0
je @write_in
jmp @continue
@write_in:
pushad

push esi
push offset sz_format
push offset buf
call wsprintf
pop esi

push NULL
push offset suc_word
push 7
push offset buf
push h_file
call WriteFile
popad


jmp @continue
@finish:


to csdsjkk
是啊,我按您的改完之后,果然运行正常了,请问为什么把ecx换成esi就正常了?为什么用ecx不行呢?不是一样的压栈和出栈吗?谢谢:0
csdsjkk 2003-11-28
  • 打赏
  • 举报
回复
偶改的程序运行没有问题呀
间谍 2003-11-28
  • 打赏
  • 举报
回复
谢谢楼上各位,保存寄存器,还有把ecx换成esi,这些我都试了,还是原来的问题。劳烦大家再帮我看看。
Yashmak 2003-11-28
  • 打赏
  • 举报
回复


@write_in:

push ad---->!!!
invoke wsprintf,offset buf,offset sz_format,esi
invoke WriteFile,h_file,offset buf,7,offset suc_word,NULL
pop ad---->!!!
jmp @continue
Yashmak 2003-11-28
  • 打赏
  • 举报
回复
invoke wsprintf,addr buf,addr sz_format,esi--?

好象还是应该用offset,因为你是在.data里定义的buf和sz_format


call WriteFile后面应该有pop esi
csdsjkk 2003-11-28
  • 打赏
  • 举报
回复
.386
.model flat,stdcall
option casemap:none

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;include定义
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

include e:\masm32\include\windows.inc
include e:\masm32\include\user32.inc
include e:\masm32\include\kernel32.inc
includelib e:\masm32\lib\user32.lib
includelib e:\masm32\lib\kernel32.lib

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;数据段
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.data?

array db 10000 dup(?) ;默认求(1-10000)素数
h_file dd ? ;文件句柄
buf db 100 dup(?) ;缓冲区
.data
g_count dd 10000 ;区间
g_bound dd 100 ;上界
suc_word dd 0 ;文件操作参数

.const

file_name db 'd:\result.txt',0 ;存放结果的文件名
sz_finish db '计算完成',0
sz_format db ' %5d ',0

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;代码段
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.code

start:
; pushad
;初始化 array全体元素为0

mov ecx, 0
mov al, 0
@init:
cmp ecx, g_count
jg @init_finish
mov array[ecx], al
inc ecx
jmp @init

@init_finish:

;计算过程

mov eax, 1
mov array[2], 0

@find_init:
inc eax
cmp array[eax], 1
je @find_init
cmp eax, g_bound
jg @find_finish
mov cx,1
@find_begin:
push eax
inc cx
mul cx
push ax
mov ax, dx
shl eax, 8
pop ax
cmp eax, g_count
jg @go_init
mov array[eax], 1
pop eax
jmp @find_begin
@go_init:
pop eax
jmp @find_init

@find_finish:

;写入结果
push NULL
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push NULL
push FILE_SHARE_READ
push GENERIC_WRITE
push offset file_name
call CreateFile
mov h_file, eax

mov esi, 1
@continue:
cmp esi, g_count
jg @finish
inc esi
cmp array[esi], 0
je @write_in
jmp @continue
@write_in:
;push esi
;push offset sz_format
;push offset buf
;call wsprintf
invoke wsprintf,addr buf,addr sz_format,esi

push NULL
push offset suc_word
push 7
push offset buf
push h_file
call WriteFile
jmp @continue
@finish:

push h_file
call CloseHandle

; popad
invoke ExitProcess,0
end start
间谍 2003-11-28
  • 打赏
  • 举报
回复
我在给每个函数调用都加了pushad和popad,情况还是那样.WriteFile只能执行一次,建立文件后,输出' 2 ',程序就挂了,而且没有运行后面的.

21,458

社区成员

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

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