为什么程序运行一段时间后会自动关闭。

aroky_zxc 2006-05-16 10:55:35
ThreadProc PROC USES edi Param:DWORD
.while TRUE
invoke GetLocalTime,addr SysTime
;得到系统时间的秒,分,时,分别在7段数码管中显示
;Code7 db 3fH,06H,5bH,4fH,66H,6dH,7dH,07H,7fH,6fH
; 0 1 2 3 4 5 6 7 8 9
;Code7是1,2,。。9的数码管编码
;Led7 db 6 dup(?)
;Led7 存储对应秒,分,时的数码管编码
xor eax,eax
xor ebx,ebx
xor ecx,ecx
mov ax,SysTime.wSecond
DIV RADIX ;RADIX = 10
mov bh,00H
mov bl,ah ;ah中存有秒数的个位数
mov ch,Code7[ebx]
mov Led7+0,ch
mov bl,al ;al中存有秒数的十位数
mov ch,Code7[ebx]
mov Led7+1,ch

mov ax,SysTime.wMinute
DIV RADIX
mov bh,00H
mov bl,ah ;ah中存有分的个位数
mov ch,Code7[ebx]
mov Led7+2,ch
mov bl,al ;al中存有分的十位数
mov ch,Code7[ebx]
mov Led7+3,ch

mov ax,SysTime.wHour
DIV RADIX
mov bh,00H
mov bl,ah ;ah中存有小时的个位数
mov ch,Code7[ebx]
mov Led7+4,ch
mov bl,al ;al中存有小时的十位数
mov ch,Code7[ebx]
mov Led7+5,ch
invoke pcicard_iowrite,01H,00H ;调用的DLL函数
mov bl,CountI
mov bh,00H
mov cl,Led7[ebx]
mov Led7I,cl
invoke pcicard_iowrite,00H,Led7I ;调用的DLL函数

mov al,CountI
.while al!=0
shl Sel,1
dec al
.endw

invoke pcicard_iowrite,01H,Sel
mov Sel,01H
.while k < 50000
inc k
dec k
inc k
.endw
mov k,0

.if CountI == 5
mov CountI,0
.else
inc CountI
.endif

.endw
ret
ThreadProc endp
程序运行主要是数码管上显示系统时间,但是好像每次都是运行同一段时间后程序自动关闭。
用VC加载.exe后调试窗口出现
The thread 0xC80 has exited with code 0 (0x0).
The thread 0xA24 has exited with code 0 (0x0).
The program 'D:\masm32\StaDigital.exe' has exited with code 0 (0x0).
...全文
2771 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
aroky_zxc 2006-05-17
  • 打赏
  • 举报
回复
谢谢zara(Kyrie eleison) ,我试试。非常感激!
zara 2006-05-17
  • 打赏
  • 举报
回复
...
mov Led7+5,ch
invoke pcicard_iowrite,01H,00H ;调用的DLL函数
mov bl,CountI
...
分别在上面的两个 mov 指令上置断点, 记录 esp 对比看一下是否相等, 相等的话, 就清除这两个断点, 再对下面的那两个 invoke 语句进行类似的操作; 如果不等, 先看看中间的 call 指令后有没有 add esp,xx 这样的指令, 如果没有, 进入 pcicard_iowrite 函数, 看看最后的 ret 是不是 ret xx 带参数出栈的. 这样就可以大致判断堆栈平衡问题出在那里了. 如果这些都没有问题, 那就是 dll 中调用的其它函数有内存 "分配-释放" 方面的问题
aroky_zxc 2006-05-17
  • 打赏
  • 举报
回复
我把程序贴出来了:这个DDL再VC下写的,在VC下调用运行内存不涨。
。asm
ThreadProc PROC USES ebx Param:DWORD
.while TRUE
invoke pcicard_ioread,00H, addr GetValue ;调用的DLL函数
invoke pcicard_iowrite,01H,GetValue ;调用的DLL函数
.endw
ret
ThreadProc endp

DLL:
define __PCICARDLIB__ extern "C"
__PCICARDLIB__ int pcicard_ioread(const unsigned char address_offset,unsigned char
*data) //参数1 为偏移地址,参数2 为数据地址指针
{
if (!PCICARDOPEN) return FAIL;
*data=PCICARD_ReadByte(hDevice,AD_PCI_BAR0,(unsigned
long)address_offset); //ADPCI_BAR0 表示为读写IO。
return SUCCESS;
}

// Function: PCICARD_ReadByte()
// Read a Byte from the card's memory/IO.
// Parameters:
// hPCICARD [in] handle to the card as received from PCICARD_Open().
// addrSpace [in] the address space of the card to access.
// dwOffset [in] offset relative to the beginning of the address space to access.
// Return Value:
// The value read from the card's memory/IO.
BYTE PCICARD_ReadByte (PCICARD_HANDLE hPCICARD, PCICARD_ADDR addrSpace, DWORD dwOffset)
{
BYTE data;
if (hPCICARD->addrDesc[addrSpace].fIsMemory)
{
BYTE *pData = (BYTE *) (hPCICARD->cardReg.Card.Item[hPCICARD->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
data = *pData; // read directly from the memory mapped range
}
else PCICARD_ReadWriteBlock(hPCICARD, addrSpace, dwOffset, TRUE, &data, sizeof(BYTE), PCICARD_MODE_BYTE);
return data;
}


__PCICARDLIB__ int pcicard_iowrite(const unsigned char address_offset,const unsigned
char data) //参数1 为偏移地址,参数2 为数据
{
if (!PCICARDOPEN) return FAIL;
PCICARD_WriteByte(hDevice,AD_PCI_BAR0,(unsigned
long)address_offset,data);
//ADPCI_BAR0 表示为读写IO。
return SUCCESS;
}
// Function: PCICARD_WriteByte()
// Write a Byte to the card's memory/IO.
// Parameters:
// hPCICARD [in] handle to the card as received from PCICARD_Open().
// addrSpace [in] the address space of the card to access.
// dwOffset [in] offset relative to the beginning of the address space to access.
// data [in] the data to write to the card's memory/IO.
// Return Value:
// None.
void PCICARD_WriteByte (PCICARD_HANDLE hPCICARD, PCICARD_ADDR addrSpace, DWORD dwOffset, BYTE data)
{
if (hPCICARD->addrDesc[addrSpace].fIsMemory)
{
BYTE *pData = (BYTE *) (hPCICARD->cardReg.Card.Item[hPCICARD->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
*pData = data; // write directly to the memory mapped range
/////////////
//delete [] pData
}

else PCICARD_ReadWriteBlock(hPCICARD, addrSpace, dwOffset, FALSE, &data, sizeof(BYTE), PCICARD_MODE_BYTE);
}

zara 2006-05-17
  • 打赏
  • 举报
回复
那问题应该是在 pcicard_iowrite 函数中了. 大致可能有这么几个原因:
1. 函数中有内存分配调用, 但没有释放的操作, 导致内存消耗逐渐增加;
2. 函数的堆栈中参数平衡问题. 比如调用者以为约定是由子程负责释放 (ret xx), 而子程认为是应该有调用者来进行平衡 (call 指令后通过 add esp, xx). 这样也会导致堆栈消耗逐步增加而耗尽溢出
aroky_zxc 2006-05-17
  • 打赏
  • 举报
回复
去掉了io读写语句后不关闭,增加堆栈大小后程序运行时间增长,再任务管理器里查看该。exe发现内存使用一直增长,知道超出允许范围后被系统强行关闭。
怎么解决清理内存?
aroky_zxc 2006-05-17
  • 打赏
  • 举报
回复
我用
MOVZX ECX,led7I
invoke pcicard_iowrite,00H,ecx
解决问题了。真的非常感谢zara(Kyrie eleison)
zara 2006-05-17
  • 打赏
  • 举报
回复
后面的 invoke pcicard_iowrite,01H,Sel 应该也有类似的问题
zara 2006-05-17
  • 打赏
  • 举报
回复
编译器的问题. 编译程序对 invoke 语句没有能够判别非 dword 类型的参数或者是没有加以正确的平衡. 所以, 恐怕你得自己先将 Led7I 赋给 eax, 再在 invoke 时使用 eax 作为参数, 而不是直接把字节类型的 Led7I 作为 dword 类型的参数:
movzx eax, Led7I
invoke pcicard_iowrite, 0, eax
aroky_zxc 2006-05-17
  • 打赏
  • 举报
回复
zara(Kyrie eleison) 我在VC下反汇编:
invoke pcicard_iowrite,01H,00H ;调用的DLL函数
反汇编成
004011F9 push 0
004011FB push 1
004011FD call pcicard_iowrite (00401444)
ESP调用前后相等。
但是
invoke pcicard_iowrite,00H,Led7I ;调用的DLL函数
反汇编成
00401216 push 0 ;ESP减少4
00401218 mov al,[Led7I (004041b9)]
0040121D movzx ax,al
00401221 push ax ;ESP减少2
00401223 push 0 ;ESP减少4
00401225 call pcicard_iowrite (00401444)
所以调用前后esp减少2,造成不等。很疑惑为什么会压入三个数,参数不是只有两个嘛?
zara 2006-05-16
  • 打赏
  • 举报
回复
StaledThread, 是由于线程没有结束机制的缘故吧. 由于 Threadproc 线程函数中除了 invoke 语句调用的 pcicard_iowrite 函数外, 并没有其它的堆栈操作, 所以, 真如果有堆栈上的问题的话, 那就应该是 pcicard_iowrite 函数的问题了
大熊猫侯佩 2006-05-16
  • 打赏
  • 举报
回复
1 将 io 读写语句去掉看看是否还关闭?

2 增大线程堆栈大小。
aroky_zxc 2006-05-16
  • 打赏
  • 举报
回复
在VC打开。exe文件,程序自动结束后会显示堆栈溢出的信息
First-chance exception in StaLedThread.exe (NTDLL.DLL): 0xC00000FD: Stack Overflow.
怎么解决啊?
aroky_zxc 2006-05-16
  • 打赏
  • 举报
回复
楼上的什么意思啊?能不能说的清楚一点。拜托了。
我把我的主线程贴出来:
WndProc proc hWin:DWORD,uMsg:DWORD,wParam :DWORD,lParam :DWORD
.if uMsg==WM_CREATE
;窗体创建
invoke pcicard_open ;没有打开设备的话
.if eax==NULL
invoke MessageBox,NULL ,addr PcicardNotOpen,addr AppName,MB_OK
invoke PostQuitMessage,NULL
.endif
mov eax,0
ret
.elseif uMsg == WM_COMMAND;两个参数wParam ,lParam
mov eax,wParam
.if lParam;lParam!=NULL,控件发出的消息
.if ax == ID_BUTTON;低16位表示按钮ID
shr eax,16
.if ax == BN_CLICKED;高16位事件通知码

.if BeginThread == 0

invoke CreateThread,NULL,NULL,offset ThreadProc,NULL,0,addr ThreadId
mov hThread,eax
mov BeginThread ,1
.endif
.endif
.endif
.endif
ret
.elseif uMsg == WM_DESTROY
;程序销毁
invoke CloseHandle,hThread
invoke pcicard_close
invoke PostQuitMessage,NULL
ret
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
对于窗口的消息还不是很清楚,请指教!

zara 2006-05-16
  • 打赏
  • 举报
回复
ThreadProc PROC USES edi ... 应该是 ThreadProc PROC USES ebx ...
不过, 这个会导致该线程自动结束吗? 主线程是在该线程结束后就结束的?
微信小程序系统教程[初级阶段],微信小程序0基础学起,讲解微信小程序开发的基础知识。 微信小程序系统教程共有“微信小程序系统教程[初级阶段]”、“微信小程序系统教程[中级阶段]——核心技术”、“微信小程序系统教程[阶段]客服消息+微信支付+九宝电商系统”。 “微信小程序系统教程[阶段]全套课程”包含: 1.微信小程序系统教程[阶段]_客服消息 2.微信小程序系统教程[阶段]_微信支付 3.微信小程序系统教程[阶段]_九宝电商系统 学习“微信小程序系统教程[阶段]”要求有微信小程序的基础。建议先学习“微信小程序系统教程[初级阶段]”、“微信小程序系统教程[中级阶段]”,后在报名“微信小程序系统教程[阶段]”。 阶段讲解的客服消息,是针对小程序的。后台程序用接近底层的技术,没有使用三方技术。这样降低同学们学习成本。 微信支付,这部分课程很有难度,要求同学们认真听讲,有不会的技术问题可以请教老师。购买课程后请联系老师,提供单号,给你源程序。 九宝电商系统是一套十分适和学习、项目的课程。既可以系统的学习微信小程序相关知识,还可以修改后上线。 “微信小程序系统教程[中级阶段]——核心技术”重点讲解微信小程序事件、组件、API 微信小程序系统教程[初级阶段],微信小程序0基础学起,讲解微信小程序开发的基础知识。 购买课程的同学,可赠送就九宝老师编写的《微信小程序开发宝典》。 购课请咨询qq2326321088

21,459

社区成员

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

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