| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4512 人关注过本帖
标题:请教一下子函数调用和字符串的问题!
取消只看楼主 加入收藏
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
 问题点数:0 回复次数:7 
请教一下子函数调用和字符串的问题!
我在做一道字符串加密题,在函数调用的时候提示出错了,而且不能将字符串从ESI里MOV到一个空字符串里,下面是我程序出错的部分

.if eax==1001
mov eax,wParam
.if eax==1001
mov bz,0
.if eax==1002
mov bz,1
invoke mm,addr s1,addr s2,bz  这里在调用的时候提示出错了,但又不知道哪里出问题了。


子函数在这里:
mm proc s1:DB,s2:db,bz:db   这句提示出错:
                            instruction or register not accepted in current CPU mode
cmp bz,0
je jiami
jmp jiemi
jiami:
mov esi,offset s
mov s1,[esi]   这里提示:invalid instruction operands
shl s1,1
add s1,3
inc byte typ[esi]   
cmp [esi],0   这里提示:invalid instruction operands
je L2
jmp jiami
jiemi:
mov esi,offset s1
mov s2,[esi]   也是:invalid instruction operands
sub s2,3
shr s2,1
inc byte typ[esi]   
cmp [esi],0   也是: invalid instruction operands
je L2
jmp jiemi
L2:ret
mm endp   这里提示:instruction or register not accepted in current CPU mode

数据在这里
s DB "hello",0
s1 db 20 dup(?)
s2 db 20 dup(?)
bz db ?
请问到底是哪里出问题了,怎么用mov s1,esi会提示出错呢?子函数应该怎么调用,我现在刚学汇编不久很多都看不懂,希望有人帮忙解释一下,感激不尽.
搜索更多相关主题的帖子: 函数 字符 
2008-11-18 11:48
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
得分:0 
我知道你的意思,我学过C,虽然不是很好,但对指针跟地址有点理解,你说
mm proc s1:DB,s2:db,bz:db  这里的地址调用我知道,是传递字符串的首地址过来,但是我不清楚汇编中指针是多少位,这里是不是可以把类型改成32位就行了?
还有从主函数
invoke mm,addr s1,addr s2,bz  
这里调用的时候就已经提示出错了,我就搞不懂是哪里出问题。

这里的 mov esi,offset s 我看得懂,知道是传递字符串的首地址,但是在执行
mov s1,[esi]  的意思不是将esi中的第一个字符的地址赋给s1吗?也要将s1改32位?

在汇编里的指针操作全都是32位的吗?那定义个8位变量是不是就不能进行指针操作?
还有像这样的题要怎么对字符串进行传递呢?

这道题用C和C++做起来很简单,我也做过,只是现在刚学汇编不久,对堆栈和汇编里的一些语句会看不明白什么意思。
2008-11-18 13:51
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
得分:0 
感谢ONEPROBLEM 的指点,不过现在在调用子函数的时候还是老问题,不知道什么原因,
我已经照cnhanxiao改了几个行参的类型,不过还是执行提示失败了...在汇编调用子函数需要怎么设置才能调用呢?是不是在传递地址的时候一定要把行参改为32位的?

我用radasm画了两个按钮,在点两个按钮的时候就激发这个过程,整个原程序在这里:


    mm proc s1:DWORD,s2:DWORD,s3:DWORD
        cmp bz,0
        je jiami
        jmp jiemi
  jiami:
        mov esi,offset s
        lea edi,s1    ;把s1的有效地址装入edi
        mov al,[esi] ;如果进行字节操作,注意用al
        mov [edi],al
        shl s1,1
        add s1,3
        inc byte ptr [esi]
        mov al,[esi] ;进行字操作的话就用ax,类推
        cmp al,0
        je L2
        jmp jiami
  jiemi:
        mov esi,offset s1
        lea edi,s2    ;把s1的有效地址装入edi
        mov al,[esi] ;如果进行字节操作,注意用al
        mov [edi],al
        sub s2,3
        shr s2,1
        inc byte ptr [esi]
        mov al,[esi]
        cmp al,0
        je L2
        jmp jiemi
     L2:ret
     mm endp
;########################################################################

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    mov        eax,uMsg
    .if eax==WM_INITDIALOG

    .elseif eax==WM_COMMAND
        mov  eax,wParam
        .if eax==1001 ;1001是按钮1
        mov  eax,wParam
        .if eax==1001
            mov bz,0            
        .if eax==1002  ;1002是按钮2
            mov bz,1
            invoke mm,addr s1,addr s2,bz
            invoke MessageBox,hWin,addr mess1, addr mtl,MB_OK            
        .endif
        .endif
        .endif
    .elseif eax==WM_CLOSE
        invoke EndDialog,hWin,0
    .else
        mov        eax,FALSE
        ret
    .endif
    mov        eax,TRUE
    ret

DlgProc endp

end start

数据在这里:

.data
mtl    db    "test my titles",0
mmsg db    "hello world!",0
s DB "hello",0
s1 dd 20 dup(0)
s2 dd 20 dup(0)
bz db ?
2008-11-19 07:58
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
得分:0 
抱歉,早上因为要上课,所以急急忙忙没弄好...
我是用radasm,里面有三个工程组,一个.asm一个.inc还有一个窗口按钮.
这是asm文件:
.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include text1.inc

.code

start:

    invoke GetModuleHandle,NULL
    mov        hInstance,eax

    invoke InitCommonControls
    invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
    invoke ExitProcess,0
    mm proc s1:DWORD,s2:DWORD,s3:DWORD
        cmp bz,0
        je jiami
        jmp jiemi
  jiami:
        mov esi,offset s
        lea edi,s1    ;把s1的有效地址装入edi
        mov al,[esi] ;如果进行字节操作,注意用al
        mov [edi],al
        shl s1,1
        add s1,3
        inc byte ptr [esi]
        mov al,[esi] ;进行字操作的话就用ax,类推
        cmp al,0
        je L2
        jmp jiami
  jiemi:
        mov esi,offset s1
        lea edi,s2    ;把s1的有效地址装入edi
        mov al,[esi] ;如果进行字节操作,注意用al
        mov [edi],al
        sub s2,3
        shr s2,1
        inc byte ptr [esi]
        mov al,[esi]
        cmp al,0
        je L2
        jmp jiemi
     L2:ret
     mm endp
;########################################################################

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    mov        eax,uMsg
    .if eax==WM_INITDIALOG

    .elseif eax==WM_COMMAND
        mov  eax,wParam
        .if eax==1001
        mov  eax,wParam
        .if eax==1001
            mov bz,0            
        .if eax==1002
            mov bz,1
            invoke mm,addr s1,addr s2,bz
            invoke MessageBox,hWin,addr mess1, addr mtl,MB_OK            
        .endif
        .endif
        .endif
    .elseif eax==WM_CLOSE
        invoke EndDialog,hWin,0
    .else
        mov        eax,FALSE
        ret
    .endif
    mov        eax,TRUE
    ret

DlgProc endp

end start

这是.inc文件

include windows.inc
include kernel32.inc
include user32.inc
include Comctl32.inc
include shell32.inc
include D:\masm32\新建文件夹\RadASM\masm\inc\radbg.inc
includelib kernel32.lib
includelib user32.lib
includelib Comctl32.lib
includelib shell32.lib

DlgProc            PROTO    :HWND,:UINT,:WPARAM,:LPARAM

.const

IDD_DIALOG1            equ 101

;#########################################################################

.data?

hInstance            dd ?

;#########################################################################
.data
mtl    db    "test my titles",0
mmsg db    "hello world!",0
s DB "hello",0
s1 dd 20 dup(0)
s2 dd 20 dup(0)
bz db ?
mess1 db "finished(XxY+Z-V)/P!",0
2008-11-19 09:57
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
得分:0 
请问ONEPROBLEM你是用什么编译器的?我这个也用得很不舒服,很多地方都用不熟悉,你能不能发你那个给我一下?还有这道题现在的问题是在调用子函数提示出错,我把子函数直接搬到主函数里,但是运行的时候还是没结果,你能不能帮我看一下是哪里出问题?

    mm proc s1:DWORD,s2:DWORD,s3:DWORD
        cmp bz,0
        je jiami
        jmp jiemi
  jiami:
        mov esi,offset s
        lea edi,s1   
        mov al,[esi]
        mov [edi],al
        shl s1,1
        add s1,3
        inc byte ptr [esi]
        mov al,[esi]
        cmp al,0
        je L2
        jmp jiami


  jiemi: ;这是解密
        mov esi,offset s1
        lea edi,s2   
        mov al,[esi]
        mov [edi],al
        sub s2,3
        shr s2,1
        inc byte ptr [esi]
        mov al,[esi]
        cmp al,0
        je L2
        jmp jiemi
     L2:ret
     mm endp

这道题是根据bz的值对字符串s进行加密和解密,加密的方法为*2+3.
加密的字符串放到S1解密的放S2...最后调用一个窗口显示出字符串...
我设置两个按钮,根据按钮给BZ赋值,0就加密,1就解密..s是原来字符串,s1是加密后字符串,s2是存放解密后字符串(就是s1解密后的).
2008-11-19 11:23
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
得分:0 
呵呵,两位版主说得对,我对汇编的指令确实很多都不够清楚,只是这道题做了好几天了,都是根据书上的指令做的,现在想先把题做完,再边看书理解那些意思,不然看完之后我怕又给忘了..
2008-11-19 13:06
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
得分:0 
呵呵,我会用心去学的,zklhp版主和ONEPROBLEM版主能不能把你们两位的Q给我,如果有不懂可以请教一下,我现在刚学不久,想不遇到不懂的地方可以找个人探讨一下..
2008-11-19 13:20
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
得分:0 
呵呵,也行那,就是怕有时看不到你们老人家在,找不到人问了那..
现在我整个程序重新修改了一下,但不知道为什么运行后那个调用显示字符的框没有出现,麻烦重新帮我看一下是哪里问题.
子函数:
string proc str1:DWORD,str2:DWORD,bz1:DWORD
        cmp bz1,0
        je jiami
        jmp jiemi
  jiami:
        mov esi,offset s
        lea edi,str1    ;把s1的有效地址装入edi
        mov al,[esi] ;如果进行字节操作,注意用al
        cmp al,0
        je L1
        shl al,1
        add al,3
        mov [edi],al
        inc byte ptr [esi]
        inc byte ptr [edi]
        mov al,[esi] ;进行字操作的话就用ax,类推
        jmp jiami
        
  jiemi:
        lea esi,str1
        lea edi,str2    ;把s1的有效地址装入edi
        mov al,[esi] ;如果进行字节操作,注意用al
        sub al,3
        shr al,1
        mov [edi],al
        inc byte ptr [edi]
        inc byte ptr [esi]
        mov al,[esi]
        cmp al,0
        je L2
        jmp jiemi
     L1:
        mov [edi],al
        invoke MessageBox,0,addr str1,addr mtl,MB_OK
     L2:
        mov [edi],al
        invoke MessageBox,0,addr str2,addr mtl,MB_OK
string endp

从主函数调用的地方:
DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    mov        eax,uMsg
    .if eax==WM_INITDIALOG

    .elseif eax==WM_COMMAND
        mov  eax,wParam
        .if eax==1001
        mov  eax,wParam
        .if eax==1001
            mov bz,0    
            invoke string,addr s,addr s1,bz     
        .if eax==1002
            mov bz,1
            invoke string,addr s1,addr s2,bz            
        .endif
        .endif
        .endif
    .elseif eax==WM_CLOSE
        invoke EndDialog,hWin,0
    .else
        mov        eax,FALSE
        ret
    .endif
    mov        eax,TRUE
    ret

DlgProc endp

顺便弱弱的说句:原来mm是属于关键字的,汗.....
2008-11-19 17:36
快速回复:请教一下子函数调用和字符串的问题!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.052559 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved