| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4514 人关注过本帖
标题:请教一下子函数调用和字符串的问题!
只看楼主 加入收藏
cnlkf
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2008-5-13
收藏
 问题点数:0 回复次数:22 
请教一下子函数调用和字符串的问题!
我在做一道字符串加密题,在函数调用的时候提示出错了,而且不能将字符串从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
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
你先理解一下它说的意思呀

mm proc s1:DB,s2:db,bz:db   这个明显有错 因为你给它的是指针 就是一个地址 是32位呀 就是一个双字 你这个当然不对了

win32下api压栈都是压双字吧

后面几个也是这个错  错误理解了指针 之类的概念

mov esi,offset s

这个执行后 esi中放的是字符串 s 就是 "hello",0  第一个字符的首地址 注意 是地址 就是个双字!!!
2008-11-18 12:52
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
建议你联系一下c语言里的指针

说实话 要是你直接学汇编可能很难 有c的基础就好点

对指针要深刻理解

偶说的可能不太明白 大概就这意思
2008-11-18 12:54
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]cnlkf[/un] 在 2008-11-18 11:48 的发言:[/bo]

我在做一道字符串加密题,在函数调用的时候提示出错了,而且不能将字符串从ESI里MOV到一个空字符串里,下面是我程序出错的部分

.if eax==1001
mov eax,wParam
.if eax==1001
mov bz,0
.if eax==1002
mo ...


说白了 就是对字符串的理解不够深刻 不知道如何处理字符串

要知道 汇编比较底层 有些东西要深刻理解 可不像vb那样啊
2008-11-18 12:58
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
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
这个程序出错的地方还蛮多了.方便的话,建议LZ把整个源程序都贴出来~~
我发现几个地方要修改一下:
1.mov s1,[esi]
  mov s2,[esi]
之类的指令是错误的,两个操作数都是内存是不行的,要用一个寄存器过渡一下.
可以这样:
lea edi,s1    ;把s1的有效地址装入edi
mov eax,[esi] ;如果进行字节操作,注意用al
mov [edi],eax
其它类推;
2.  cmp [esi],0 这种比较指令,其中得有一个是寄存器.
可以这样:
mov al,[esi] ;进行字操作的话就用ax,类推
cmp al,0
3.对于子程序的调用,除了参数要正确之外,还得注意保存一些重要的寄存器.
可以在子程序调用时,用pushad 和popad这两条指令.
2008-11-18 18:12
cnhanxiao
Rank: 2
等 级:新手上路
威 望:4
帖 子:124
专家分:0
注 册:2008-10-17
收藏
得分:0 
回复 5# 的帖子
mm proc s1:DB,s2:db,bz:db

mm proc s1:DWORD,s2:DWORD,s3:DWORD

因为参数都是靠堆栈传递进来的,所以参数都是32位的。

还有绑架成版主的?拒绝做版主——对不起啊!
2008-11-18 18:54
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
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
建议LZ贴出完整的程序~~
程序从哪里开始,start呢?
程序什么时候退出,exitprocess呢?
2008-11-19 08:14
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
快速回复:请教一下子函数调用和字符串的问题!
数据加载中...
 
   



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

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