首页
社区
课程
招聘
[旧帖] [求助]MASM32V9编译怎么不行呀? 0.00雪花
发表于: 2008-2-20 15:01 8437

[旧帖] [求助]MASM32V9编译怎么不行呀? 0.00雪花

2008-2-20 15:01
8437
想学汇编,网上找的代码怎么编译不了

.386
.module flat,stdcall           ;这里我们用stdcall 就是函数参数 压栈的时候从最后一个开始压,和被调用函数负责清栈
option casemap:none            ;区分大小写

includelib msvcrt.lib          ;这里是引入类库 相当于 #include<stdio.h>了      
printf  PROTO C:DWORD,:VARARG  ;这个就是声明一下我们要用的函数头,到时候 汇编程序会自动到msvcrt.lib里面找的了
                               ;:VARARG 表后面的参数不确定 因为C就是这样的printf(const char *, );
                              ;这样的函数要注意 不是被调用函数负责清栈 因为它本身不知道有多少个参数
                              ;而是有调用者负责清栈  下面会详细说明
.data
szTextFmt  BYTE '%d',0        ;这个是用来类型转换的,跟C的一样,字符用字节类型
a          dword 1000         ;假设
b          dword 2000         ;处理数值都用双字 没有int 跟long 的区别

;/**//////////////////////////////////////////////////////////////////////////////////////////
.code

_test proc A:DWORD,B:DWORD
      push ebp
      mov  ebp,esp
      mov  eax,dword ptr ss:[ebp+8]
      add  eax,1
      mov  edx,dword ptr ss:[ebp+0Ch]
      add  edx,100
      add  eax,edx
      pop  ebp      
      retn 8
_test endp

_main proc
      push dword ptr ds:b       ;反汇编我们看到的b就不是b了而是一个[*****]数字 dword ptr 就是我们在ds(数据段)把[*****]
                                ;开始的一个双字长数值取出来
      push dword ptr ds:a       ;跟她对应的还有 byte ptr ****就是取一个字节出来 比如这样 mov  al,byte ptr ds:szTextFmt
                                ;就把 % 取出来 而不包括 d
      call _test                  
      push eax                  ;假设push eax的地址是×××××
      push offset szTextFmt
      call printf
      add  esp,8
      ret            
_main endp
end  _main

error A2008: syntax error : module
error A2013: .MODEL must precede this directive
error A2034: must be in segment block
error A2034: must be in segment block
error A2034: must be in segment block
error A2013: .MODEL must precede this directive
error A2034: must be in segment block : _test
error A2034: must be in segment block
error A2034: must be in segment block
error A2034: must be in segment block
error A2034: must be in segment block
error A2034: must be in segment block
error A2034: must be in segment block
error A2034: must be in segment block
error A2034: must be in segment block
error A2034: must be in segment block
fatal error A1010: unmatched block nesting : _test
Incremental Linker Version 5.12.8078
Microsoft Corp 1992-1998. All rights reserved.

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
2
.386
.model flat, stdcall
option casemap :none  
.code
start:
        ret
end start

帖个最简单的
2008-2-20 15:13
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我改成了下面的,可是运行时怎么出错呀
.386
.model flat,stdcall           ;这里我们用stdcall 就是函数参数 压栈的时候从最后一个开始压,和被调用函数负责清栈
option casemap:none            ;区分大小写

includelib \masm32\lib\msvcrt.lib          ;这里是引入类库 相当于 #include<stdio.h>了      
printf  PROTO C:DWORD,:VARARG  ;这个就是声明一下我们要用的函数头,到时候 汇编程序会自动到msvcrt.lib里面找的了
                               ;:VARARG 表后面的参数不确定 因为C就是这样的printf(const char *, );
                              ;这样的函数要注意 不是被调用函数负责清栈 因为它本身不知道有多少个参数
                              ;而是有调用者负责清栈  下面会详细说明
.data
szTextFmt  BYTE '%d',0        ;这个是用来类型转换的,跟C的一样,字符用字节类型
a          dword 1000         ;假设
b          dword 2000         ;处理数值都用双字 没有int 跟long 的区别

;/**//////////////////////////////////////////////////////////////////////////////////////////
.code

_test proc A:DWORD,B:DWORD
      push ebp
      mov  ebp,esp
      mov  eax,dword ptr ss:[ebp+8]
      add  eax,1
      mov  edx,dword ptr ss:[ebp+0Ch]
      add  edx,100
      add  eax,edx
      pop  ebp      
      retn 8
_test endp

_main proc
      push dword ptr ds:b       ;反汇编我们看到的b就不是b了而是一个[*****]数字 dword ptr 就是我们在ds(数据段)把[*****]
                                ;开始的一个双字长数值取出来
      push dword ptr ds:a       ;跟她对应的还有 byte ptr ****就是取一个字节出来 比如这样 mov  al,byte ptr ds:szTextFmt
                                ;就把 % 取出来 而不包括 d
      call _test                  
      push eax                  ;假设push eax的地址是×××××
      push offset szTextFmt
      call printf
      add  esp,8
      ret            
_main endp
end  _main

start:
  call _main
end start
2008-2-20 15:58
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
4
_test proc A:DWORD,B:DWORD
      push ebp
      mov  ebp,esp

      mov  eax,dword ptr ss:[ebp+8]
      add  eax,1
      mov  edx,dword ptr ss:[ebp+0Ch]
      add  edx,100
      add  eax,edx
      pop  ebp      
      retn 8

  ret
_test endp

红的用不到,编译时会自动加上去的。
后两行直接换成ret
2008-2-20 16:22
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
改成这个不出错了,可是为什么不出现printf结果呀?
_main是不是已经相当于start:那里了?

.386
.model flat,stdcall           ;这里我们用stdcall 就是函数参数 压栈的时候从最后一个开始压,和被调用函数负责清栈
option casemap:none            ;区分大小写

includelib \masm32\lib\msvcrt.lib          ;这里是引入类库 相当于 #include<stdio.h>了      
printf  PROTO C:DWORD,:VARARG  ;这个就是声明一下我们要用的函数头,到时候 汇编程序会自动到msvcrt.lib里面找的了
                               ;:VARARG 表后面的参数不确定 因为C就是这样的printf(const char *, );
                              ;这样的函数要注意 不是被调用函数负责清栈 因为它本身不知道有多少个参数
                              ;而是有调用者负责清栈  下面会详细说明
.data
szTextFmt  BYTE '%d',0        ;这个是用来类型转换的,跟C的一样,字符用字节类型
a          dword 1000         ;假设
b          dword 2000         ;处理数值都用双字 没有int 跟long 的区别

;/**//////////////////////////////////////////////////////////////////////////////////////////
.code
_test proc A:DWORD,B:DWORD
       mov  eax,dword ptr ss:[ebp+8]
      add  eax,1
      mov  edx,dword ptr ss:[ebp+0Ch]
      add  edx,100
      add  eax,edx
           
      ret
_test endp

_main proc
      push dword ptr ds:b       ;反汇编我们看到的b就不是b了而是一个[*****]数字 dword ptr 就是我们在ds(数据段)把[*****]
                                ;开始的一个双字长数值取出来
      push dword ptr ds:a       ;跟她对应的还有 byte ptr ****就是取一个字节出来 比如这样 mov  al,byte ptr ds:szTextFmt
                                ;就把 % 取出来 而不包括 d
      call _test                  
      push eax                  ;假设push eax的地址是×××××
      push offset szTextFmt
      call printf
      add  esp,8
      ret

            
_main endp
end  _main

start:
call _main
ret
end start
2008-2-20 16:41
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
6
我没用过printf,不过他看起来向原来dos界面下的一个函数。
现在流行win32,何以不来个MessageBox呢?
2008-2-20 16:49
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
用MESSAGEBOX怎么把数字转成字符串呀?

_main是不是已经相当于start:那里了?
2008-2-20 16:57
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
子过程把返回值存到EAX,然后调用函数去读EAX??
2008-2-20 17:00
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
9
可用 wsprintf 来转换。
不明白你问的_main的原意,汇编里不认识main 只认识start.
从start:处开始,到end start 处结束。
大多数API的返回值都在eax里,你可以让结果返回到eax。
也可以传个参数返回来参数里。
2008-2-20 17:07
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
printf是在DOS下输出的吧,为啥它不输出呀?

我没用START:发现会执行_MAIN PROC 开始的命令
2008-2-20 17:27
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
11
_main endp
end  _main <- 估计是他在作怪

start:
call _main
ret
end start
2008-2-20 18:05
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢,可以输出了,可是执行完总是出现错误,就是遇到问题需要关闭

.386
.model flat,stdcall        
option casemap:none            

includelib \masm32\lib\msvcrt.lib
printf  PROTO C:DWORD,:VARARG

.data
msg  db "xxxxxxxxxxxx",0    //",0"是干嘛的?

.code
start:
push offset msg
call printf
add esp,4
end start
2008-2-20 23:17
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
13
msg db "xxxxxxxxxxxx",0 //",0"是干嘛的?

那个是字符串结束标志。

之所以出现错误估计是你没有给这个程序一个正常的结束造成的。
2008-2-20 23:37
0
雪    币: 213
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
masm32v9的编译环境我也没能成功编译,后来我换成radasm就行了,其实我觉得radasm已经很好了。
2008-2-21 00:12
0
雪    币: 220
活跃值: (117)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
radasm 就是用的masm32啊,你在新建project的时候可以看到命令啊。
2008-2-21 10:01
0
游客
登录 | 注册 方可回帖
返回
//