对于我的任务,我试图编写像C ++插入一样的插入函数。 我的函数应该将一个字符串插入到某个位置的其他字符串中。
输入
Be my good friend today
输出:
Insert PROC PROC uses edi esi ebx ecx,
destination:DWORD ,
source:DWORD,
position:DWORD
mov esi,destination ;add esi address of str
add esi,position
add esi,4 ;lenght of source
mov edi,destination
add edi,position
;I don't know what should I do in here
;How should I make room in the middle of destination ?
;How should I insert at certain position + source length :-(
;Also, I shouldn't use loop and lea.
rep movsb
Insert ENDP
我应该如何在琴弦的中间腾出空间?
到目前为止,这是我的代码。
CONSTRAINT [FK_T_Stanje_T_Artikli]
FOREIGN KEY ([StanjeId])
REFERENCES [dbo].[T_Artikli] ([ArtikliId])
答案 0 :(得分:3)
我将避免提供任何代码,因为我无意为您编写任务,但我会尝试解释您将如何完成它。
我将假设以下内容:
1)destination
在其地址处有足够的内存来保存已完成的字符串而不会覆盖任何其他变量。
2)您实际上想要插入"good "
(带有尾随空格),而不是"good"
,因为如果您插入"good"
,最终会导致"Be my goodfriend today"
(没有好人和朋友之间的空间)。
3)你实际上打算指定位置5而不是位置6,因为C ++ insert
使用从零开始的位置(位置0是第一个字符,位置1是第二个,等等)。
您的第一步是复制字符串的右侧部分以腾出空间。您将从插入的起始位置复制字符到起始位置加上要插入的字符串的大小,最后是以下内容:
destination : Be my frienfriend today
这里有一个问题:您必须从destination
的末尾复制向后以避免覆盖尚未复制的字符 - 如果您从偏移量6开始并且复制到偏移11,你将覆盖需要首先复制到偏移16的偏移11的值,你最终会得到这样的结果:
destination : Be my frienfrienfrienfri
通过向后复制,可以避免这个问题。使用适当的dec
或sub
运算符进行简单的条件跳转可以正常工作。
在为上面指定的源字符串腾出空间之后,可以正确加载寄存器并使用rep movsb
将源复制到指定位置的目标位置,覆盖已复制的字符。
由此,destination
将包含"Be my good friend today"
。
答案 1 :(得分:0)
你应该为新的"字符串预留内存"长度为og的原始字符串+要插入的字符串的长度。从源字符串中复制下一个字符,直到指定的位置(根据字符宽度使用LODSB或LODSW)。指向新输出字符串并将edi指向源数组。将CX设置为位置值。这会将字符从源复制到新的目标内存。然后将edi指向要插入的字符串,并将cx设置为要插入的字符串的长度。再次运行LODSW,最后将edi指向源字符串的位置,并将cx设置为源字符串的长度减去位置,并最后运行lodsw。
答案 2 :(得分:0)
到新字符串:
从原件复制字符,然后复制新字符,然后复制原件的尾部。
在就地:
复制字符串的尾部以创建一个间隙来存储新字符串。这就像memmove
:由于副本的来源和目的地重叠,您应该从最后一个字符开始,这样您就不会覆盖尚未复制的字符。它也与InsertionSort's copying to make room for a new element相同。
您可能想要使用两个寄存器来跟踪源位置和目的地位置。
答案 3 :(得分:0)
您的问题可以通过两个函数来解决:第一个函数将字符串的字符从SI位置开始向右移位一个位置,第二个函数将第一个函数调用第一个CX次。这些函数是腾出空间来插入新字符串所必需的(我想你可以将它们合并到一个函数中)。之后,使用源字符串覆盖目标字符串很容易。我选择" $"要完成字符串,您可以用零或其他方式更改它:
<强> shift_right_once 强>
;---------------------------------------------------
;SHIFTS ONE POSITION TO THE RIGHT ALL THE CHARACTERS
;OF A STRING STARTING AT POSITION POINTED BY "SI".
;STRING MUST FINISH WITH "$".
;EXAMPLE: SI = 6
; INPUT = 'Be my friend today$$$$$$$$$$$$$$$$'
; OUTPUT = 'Be my ffriend today$$$$$$$$$$$$$$$'
;MODIFIED REGISTERS : AX, SI.
shift_right_once proc
mov al, [ si ] ;FIRST CHAR TO START PROCESS.
shifting:
cmp al, '$'
je end_shifting ;IF ( END OF STRING )
inc si
mov ah, [ si ]
mov [ si ], al
xchg al, ah
jmp shifting
end_shifting:
ret
shift_right_once endp
<强> shift_right_cx 强>
;---------------------------------------------------
;SHIFTS "CX" POSITIONS TO THE RIGHT ALL THE CHARACTERS
;OF A STRING STARTING AT POSITION POINTED BY "SI".
;STRING MUST FINISH WITH "$".
;EXAMPLE: SI = 6
; CX = 3
; INPUT = 'Be my friend today$$$$$$$$$$$$$$$$'
; OUTPUT = 'Be my ffffriend today$$$$$$$$$$$$$'
;MODIFIED REGISTERS : AX, CX.
shift_right_cx proc
push si
call shift_right_once ;CALL PREVIOUS FUNCTION.
pop si
loop shift_right_cx
ret
shift_right_cx endp
下一个小程序(用EMU8086制作)展示了如何使用它们:
.stack 100h
.data
destination db 'Be my friend today$$$$$$$$$$$$$$$$'
source db 'good $'
length dw 5 ;LENGTH OF "SOURCE".
position dw 6 ;POSITION TO INSERT.
.code
mov ax, @data
mov ds, ax
mov es, ax
;SHIFT CHARS TO THE RIGHT TO MAKE ROOM FOR NEW STRING.
mov cx, length ;HOW MANY CHARS TO PUSH.
mov si, offset destination
add si, position
call shift_right_cx
;OVERWRITE OLD CHARS WITH THE NEW ONES.
mov cx, length ;HOW MANY NEW CHARS.
mov di, si ;DI = DESTINATION.
mov si, offset source ;SI = SOURCE.
rep movsb ;DO { [DI]=[SI] } WHILE CX>0.
;WAIT FOR A KEY.
mov ah, 0
int 16h
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;---------------------------------------------------
;SHIFTS "CX" POSITIONS TO THE RIGHT ALL THE CHARACTERS
;OF A STRING STARTING AT POSITION POINTED BY "SI".
;STRING MUST FINISH WITH "$".
;EXAMPLE: SI = 6 |
; CX = 3
; INPUT = 'Be my friend today$$$$$$$$$$$$$$$$'
; OUTPUT = 'Be my ffffriend today$$$$$$$$$$$$$'
;MODIFIED REGISTERS : AX, CX.
shift_right_cx proc
push si
call shift_right_once ;SHIFT RIGHT CHARACTERS ONCE.
pop si
loop shift_right_cx
ret
shift_right_cx endp
;---------------------------------------------------
;SHIFTS ONE POSITION TO THE RIGHT ALL THE CHARACTERS
;OF A STRING STARTING AT POSITION POINTED BY "SI".
;STRING MUST FINISH WITH "$".
;EXAMPLE: SI = 6 |
; INPUT = 'Be my friend today$$$$$$$$$$$$$$$$'
; OUTPUT = 'Be my ffriend today$$$$$$$$$$$$$$$'
;MODIFIED REGISTERS : AX, SI.
shift_right_once proc
mov al, [ si ] ;FIRST CHAR TO START PROCESS.
shifting:
cmp al, '$'
je end_shifting ;IF ( END OF STRING )
inc si
mov ah, [ si ]
mov [ si ], al
xchg al, ah
jmp shifting
end_shifting:
ret
shift_right_once endp
希望这会对你有所帮助。