请教在masm的子程序proc中怎么声明一个字符串变量?

shier2817 2014-12-21 10:26:47
我是用在别的语言的内嵌汇编,这个语言直接支持置入汇编的机器码,所以我都是在外面写好了功能,生成机器码再调用。
而为了方便,该语言在每个子程序进入前都隐含的执行了ENTER,也就是 push ebp, mov ebp,esp 这个;
换句话说,我这里运行的汇编代码实际上就是masm中的一个子程序而已:

子程序 PROC
push ebp
mov ebp,esp ;这两句默认就有了,是隐藏的看不见
可以写入汇编的机器码……
子程序 ENDP

当然,我可以直接在第一句来个leave让他隐含的指令回去,但是一般没什么意义。。。哦说多了,这些都不是我想问的;
我只是在表达,这里仅仅是汇编中.code中的一个小小的proc,我应该不可以像完整的汇编代码那样声明一个全局的字符串变量:
变量 db "我要声明的字符串", 0
貌似这样是不行的,关于这个问题其实我搜索了好长时间都没有比较明确的答案。。。
比如masm32中带了一些宏,在那个“macros.asm”文件里,比如CTXT,CADD,szText 这些都是用于字符串的,但是我试了试不好用(或许是我不会用,也没找到具体演示的例子),首先我不是把字符串向API里传递参数,我最大的需求的将其放入esi或edi中(当然放的是字符串地址啦);
假设我要在这个子程序中产生一个字符串:"abcabc",我现在只知道最笨的办法:
local @txt[7]:byte
然后将其每个字节赋值为ASCII:61h, 62h, 63h, 61h, 62h, 63h, 0
也就是说我得写7句指令。。。我晕,我觉得肯定有比这个正常的方法吧?要是我的字符串长一些,那可咋整啊?

请前辈教教我:在子程序中声明一个字符串变量,并将其地址赋值给esi即可。。。
万分感激!
...全文
383 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
pathletboy 2014-12-22
  • 打赏
  • 举报
回复
.386
.model flat, stdcall
.code
start:
jmp next
szStr db "12345678", 0
next:
call getPtr
getPtr:
pop esi
add esi, -14  ;call getPtr opcode长度5字节+字符串长度9字节
end start
end
pathletboy 2014-12-22
  • 打赏
  • 举报
回复
总算看明白你的意思了,一会写一段范例代码,可以解决你的问题。
pathletboy 2014-12-22
  • 打赏
  • 举报
回复
masm像我这么写,经过测试是没有问题的。虽然都是汇编,但是编译器不同,语法是略有不同的。请查阅易语言嵌入式汇编的语法。
「已注销」 2014-12-22
  • 打赏
  • 举报
回复
我生成的机器码反汇编后跟您那个图可大不一样,我竟然是这样的代码:
「已注销」 2014-12-22
  • 打赏
  • 举报
回复
貌似还是不可行,这应该跟我内嵌汇编的语言有关,叫做易语言,实际上他并不支持真正的内嵌汇编,只支持嵌入机器码。。 简单说,就是一段汇编子程序【经过编译之后】的字节码我才能加到这个语言中,这就会引发一个问题: 变量 db xxx 这样的数据貌似是固定地址的吧,也就是说,我在masm32这样写,等编译的时候,他已经被初始化好了,地址是固定的,那拿着这个地址的机器码放到我的语言上,肯定地址是不对的,所以我才得到: mov esi, offset szStr mov eax, esi ;此时直接返回,结果竟然是52。。。。一看就不是个有效的内存地址。。。 貌似只有最恶心的方法了: 我local 局部变量[字节数]:byte 然后把我需要的字符串转换成字节,一个个(当然可以2个4个的)填充到局部变量里面了。。。悲催啊。。。
pathletboy 2014-12-22
  • 打赏
  • 举报
回复
.386
.model flat, stdcall
.code
start:
jmp next
szStr db "12345678",0
next:
mov esi, offset szStr
l:
lodsb
test al,al
jnz l
end start
end
这段代码,就不停的按字节读字串,直到\0为止。
pathletboy 2014-12-22
  • 打赏
  • 举报
回复
.386
.model flat, stdcall
.code
start:
jmp next
szStr db "12345678",0
next:
mov edi, offset szStr
end start
end


这段测试代码反汇编后检查了,没有问题。

「已注销」 2014-12-22
  • 打赏
  • 举报
回复
嗯嗯,多谢,我是要变量的定义方法。。。实在做不到变量,常量也可以; 而您说的只读,其实我没有违法规则哦。。。 我测试里lodsb,只是读取哦,可没对其写入。。。但是像前面那样放入edi的,貌似只是偏移而不是地址。。。 我想可能要用call 标号 来跳转,然后pop出代码地址吧好像,就是那种代码重定位技术,可是我不太会弄。。。
pathletboy 2014-12-22
  • 打赏
  • 举报
回复
仔细看了下你的题目,你是要字符串变量,那我这代码不合适,手头没有masm环境,晚上点我再帮你看看。
pathletboy 2014-12-22
  • 打赏
  • 举报
回复
这个字符串在code段中,是只读的,如果你尝试写必然会产生异常崩溃。
「已注销」 2014-12-22
  • 打赏
  • 举报
回复
引用 1 楼 pathletboy 的回复:
	jmp next
	szStr db "12345678",0
	next:
	mov edi, offset szStr
您这个跟我前面提到的那些宏的原理基本一样。。。首先我不太明白这是啥逻辑,因为跳过了还能声明变量挺奇特的,当然,如果能好用,我不明白也行,可是不好用: 我将这个地址放入edi后,是要和这个子程序传递的一个参数(这个参数是另外一个字符串的指针)进行对比看看它们是否相等; 而您这一句:mov edi, offset szStr,好像只可以获取 szStr 在本程序的偏移量吧,而不是他的读取指针,因为我接着这个做过2个测试: 1、我直接把这个edi的值给eax立即返回,没有向下进行,结果返回的值是52,这肯定不是内存地址啊,应该是szStr相对本程序的偏移哦。。 2、我将edi的值给esi,然后 lodsb,结果是崩溃。。。这也证明了是没法读取的。。。 所以,我怎么得到 szStr 的读取指针放入edi呢???
「已注销」 2014-12-22
  • 打赏
  • 举报
回复
引用 12 楼 pathletboy 的回复:
.386
.model flat, stdcall
.code
start:
jmp next
szStr db "12345678", 0
next:
call getPtr
getPtr:
pop esi
add esi, -14  ;call getPtr opcode长度5字节+字符串长度9字节
end start
end
哇哈哈,您太厉害了,也很耐心,多谢,就是这个意思。。。这个就是前面我提到过的代码重定位。。我开始没太整明白,看了您的代码有感觉了。。。貌似不用那么麻烦,我这样就可以直接取到字符串地址:

call next
szStr db "12345678",0
next:
pop esi
是不是可以这样用啊?我测试了貌似正确哦。。。多谢您咯!结贴给分啦。。。
pathletboy 2014-12-21
  • 打赏
  • 举报
回复
	jmp next
	szStr db "12345678",0
	next:
	mov edi, offset szStr

21,458

社区成员

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

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