字符串拷贝复制问题

sign21 2009-06-16 06:34:28
StringCopy proc lpString1,lpString2,ddCount
mov esi,lpString2
mov edi,lpString1
cld
mov ecx,ddCount
rep movsb
_StringCopy endp

请问这里边哪里错了 DS和ES 是一样的 ,esi和edi 也正常加了 可是 movsb 没有把lpString2里边的数据拷贝到lpString1 各位大虾帮帮忙。
...全文
211 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tippisum 2009-06-16
  • 打赏
  • 举报
回复
哦……还有,那两个include是我的bootsector用到的宏定义。所以编译的时候可以删掉它们。
Tippisum 2009-06-16
  • 打赏
  • 举报
回复
这个应该是没有问题的。我用bochs调试了这个过程,没有发现问题。
程序如下:


.386p
.model flat,stdcall
option casemap:none
assume fs:nothing,gs:nothing
include cmmrc.inc
include bootdef.inc

.code
org 0F000h
jmp start
StringCopy proc lpString1,lpString2,ddCount
mov esi,lpString2
mov edi,lpString1
cld
mov ecx,ddCount
rep movsb
ret
StringCopy endp

s1 db ' '
s2 db '1234'

start:
mov esp,120000h
invoke StringCopy,addr s1,addr s2,4



jmp $


end start


编译选项:

ML.EXE /coff init.asm /link /subsystem:posix /out:init.bin /base:0

生成init.bin后用二进制编辑器去掉文件头部0xF200h的内容。
其中PE文件头256字节,剩下的是使用org 0F000h对齐所产生的垃圾内容。

与bootsector一起组成a.img映像,用bochs Debugger加载之。

---------------------------------------------------------------

bootsector摘要:

设置如下GDT:
0x0000 0x0000000000000000 ;空描述符
0x0008 0x00CF9A000000FFFF ;系统代码段描述符(基址=0,限长=4GB,优先级=0,可执行/读)
0x0010 0x00CF92000000FFFF ;系统数据段描述符(基址=0,限长=4GB,优先级=0,可读/写)

设置CS=0x0008,DS=ES=SS=0x0010

关闭所有中断。

init.bin被加载到内存0x00010000开始的地方,并在保护模式下运行。

---------------------------------------------------------------

调试结果:
以下为bochs控制台调试记录:


(0) [0x00010000] 0008:0000000000010000 (unk. ctxt): jmp .+0x0000001b (0x0001001d
) ; eb1b
<bochs:3> p
Next at t=8698474
(0) [0x0001001d] 0008:000000000001001d (unk. ctxt): mov esp, 0x00120000 ;
bc00001200
<bochs:4> p
Next at t=8698475
(0) [0x00010022] 0008:0000000000010022 (unk. ctxt): push 0x00000004 ;
6a04
<bochs:5> p
Next at t=8698476
(0) [0x00010024] 0008:0000000000010024 (unk. ctxt): push 0x00010019 ;
6819000100
<bochs:6> p
Next at t=8698477
(0) [0x00010029] 0008:0000000000010029 (unk. ctxt): push 0x00010015 ;
6815000100
<bochs:7> p
Next at t=8698478
(0) [0x0001002e] 0008:000000000001002e (unk. ctxt): call .+0xffffffcf (0x0001000
2) ; e8cfffffff
<bochs:8> x /64xmb 0x10000
[bochs]:
0x0000000000010000:EB 1B 55 8B EC 8B 75 0C 8B 7D 08 FC 8B 4D 10 F3
0x0000000000010010:A4 C9 C2 0C 00 20 20 20 20 31 32 33 34 BC 00 00
0x0000000000010020:12 00 6A 04 68 19 00 01 00 68 15 00 01 00 E8 CF
0x0000000000010030:FF FF FF EB FE 00 00 00 00 00 00 00 00 00 00 00
<bochs:9> p
Next at t=8698491
(0) [0x00010033] 0008:0000000000010033 (unk. ctxt): jmp .+0xfffffffe (0x00010033
) ; ebfe
<bochs:10> x /64xmb 0x10000
[bochs]:
0x0000000000010000:EB 1B 55 8B EC 8B 75 0C 8B 7D 08 FC 8B 4D 10 F3
0x0000000000010010:A4 C9 C2 0C 00 31 32 33 34 31 32 33 34 BC 00 00
0x0000000000010020:12 00 6A 04 68 19 00 01 00 68 15 00 01 00 E8 CF
0x0000000000010030:FF FF FF EB FE 00 00 00 00 00 00 00 00 00 00 00


注意两次Dump中红色部分的变化。红色即为s1,也就是String1,蓝色的是s2,也就是String2。
可以看到,这个程序已经正确地完成了复制。
Tippisum 2009-06-16
  • 打赏
  • 举报
回复
这个跟只跟段设置有关。
32位数据段默认就是使用esi和edi的。(我在bochs里面做了试验)

一个bootsector把如下汇编程序对应的二进制文件加载到0x10000并切换到保护模式运行(编译器使用MASM6.14,编译连接之后使用二进制编辑器手工处理成纯二进制文件)


start:
rep movsb
jmp $


bochs Debugger这样解释rep movsb:
(0) [0x00010000] 0008:0000000000010000 (unk. ctxt): rep movsb byte ptr es:[edi], byte ptr ds:[esi] ; f3a4

证明这里确实使用了esi和edi。
zhanglei042681 2009-06-16
  • 打赏
  • 举报
回复
movsb 好像默认si,di,而不是esi,edi
你将rep movsb 改为 rep movsb byte ptr es:【edi】,byte ptr ds:【esi】试试看。
Tippisum 2009-06-16
  • 打赏
  • 举报
回复
不是,已经是lp了,所以它的内容就是指针。
lea的话会取到堆栈里面。
buzuibuxiu 2009-06-16
  • 打赏
  • 举报
回复
我不知道你的这个lpstring1和lpstring2是什么?
如果你想将二者的偏移地址分别送入esi和edi的话,那么
好象是lea和mov esi,offset lpstring1吧

21,500

社区成员

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

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