我需要emu8086中的字符串帮助。我初始化了一个字符串:
str1 db "0neWord"
我有一个空字符串:
str2 db ?
现在我需要检查str1
中的所有字母并复制到str2
,但如果str1
中的字母为0,我需要将其替换为O.如果不是,我需要复制这封信。
我该怎么做?
答案 0 :(得分:2)
str2 db ?
不是空字符串。 db
代表"定义字节" ,而?
代表单个未初始化的字节。
db "0neWord"
是汇编程序的便利,它将编译成一系列定义为'0', 'n', 'e', ..., 'd'
的字节。没有"字符串"输入汇编程序,一切都被编译成机器代码,可以看作是一系列字节。什么"键入"数据存储在内存中取决于用于访问它们的指令,但在内存中,所有内容都只是一系列字节,可以这样查看。
这可能是您检查emu8086调试器文档的好时机,在将代码加载到调试器后查看地址str1
的内存,看看它是如何编译的。
因此,只要您将第二个字节从str1
复制到str2
,您就会开始覆盖一些您不会覆盖的内存。
要分配一些固定大小的内存缓冲区,您可以使用例如str2 db 100 DUP(?)
对?
执行100次db
定义,从而在那里保留100个字节的内存,下一个机器代码字节相同的部分将在str2+100
地址之外编译。
使用str1
"字符串"执行任何操作你需要知道:
1)它在内存中的地址,x86汇编程序有很多方法可以实现,但最简单的两个是:
mov <r16>,OFFSET str1
(r16是任何16b寄存器)lea <r16>,[str1]
(在这种情况下做同样的事情) 2)它的大小或结构。你没有在那里放置任何结构,比如nul-terminated字符串在其末尾有值0
的字节,或者显示字符串的DOS int 21h, ah=9
服务期望字符串以美元符号{{1}终止所以你至少需要大小。汇编程序的'$'
指令和&#34;当前位置&#34;可用于计算EQU
的大小,如下所示:
str1
嗯,我试着通过阅读一些文档来验证这一点,但是我很难找到任何好的完整的emu8086文档(找到类似&#34;引用&#34;及其&## 39;完全没有汇编指令的描述。)
我想知道为什么这么多人仍然依赖于这个,而不是linux + nasm /类似的,它们是完全免费的,开源的并且有文档记录。
所以,让我们希望emu8086像MASM / TASM一样工作,并且我仍然能够正确地回忆起语法,那么上面提到的大小定义应该可行。否则,请参阅您的示例/文档。
最后,如果你有地址,大小和足够大的目标缓冲区(再次加载它的地址,你可以在emu8086中使用str1 db "0neWord"
str1size EQU $-str1 ; "$" is assemblers "current_address" counter
或OFFSET
),你可以编写你的任务例如以这种方式:
lea
嗯..结果是&#34;伪代码&#34;是完整的x86代码,你只需要为伪代码分配实际的寄存器,并在源代码中的任何地方替换它们。
我试图在那里提出非常广泛的评论(我的观点),因此可以理解所使用的每条指令。您应该使用英特尔的指令参考指南查阅每个指南,并将其与您可用于汇编的任何教程/课程进行交叉阅读,直到您感觉自己了解寄存器,内存等为止。
还可以通过指令调试代码指令,在每条指令后检查CPU(寄存器值,标志)和存储器内容的状态,以了解它是如何工作的。
答案 1 :(得分:2)
有多种方法可以做到这一点。以下是一些例子:
1)使用字符串说明:
.model small
.data
str1 db "0neWord$"
size equ $-str1
str2 db size dup ('')
.code
main:
mov ax, @data
mov ds, ax
mov cx, size
cld ; DF might have been set, but we want lodsb to go forwards
lea si, str1
mov ax, 0
mov bx, 0
copyStr:
lodsb ;str1 to al
cmp al, '0'
je alterChar
mov str2[bx], al
jmp continue
alterChar:
mov str2[bx], 'o'
continue:
inc bx
loop copyStr
mov str2[bx], '$'
mov ah, 09h
lea dx, str2
int 21h
mov ah, 04ch
int 21h
end main
2)没有字符串说明:
.model small
.data
str1 db "0neWord$"
str2 db ?
.code
main:
mov ax, @data
mov ds, ax
mov si, 0
call copyStr
mov ah, 09h
lea dx, str2
int 21h
mov ah, 04ch
int 21h
copyStr proc
mov bx, 0
compute:
mov bl, str1 [si]
cmp bl, '0'
je alterChar
mov str2[si], bl
jmp continue
alterChar:
mov str2 [si], 'o'
continue:
inc si
cmp str1[si], '$'
je return
jmp compute
return:
mov str2[si], '$'
ret
copyStr endp
end main
了解有关字符串说明的详情
3)使用lodsb / stosb并简化/优化:
.model small
.data
str1 db "0neWord$"
size equ $-str1
str2 db size dup ('')
.code
main:
mov ax, @data
mov ds, ax
mov es, ax ; stosb stores to [es:di]
mov si, OFFSET str1
mov di, OFFSET str2
cld ; make sure stosb/lodsb go forwards
; copy SI to DI, including the terminating '$'
copyStr: ; do {
lodsb ; str1 to al
cmp al, '0'
je alterChar
doneAlteration:
stosb ; al to str2
cmp al, '$'
jne copyStr ; } while(c != '$')
mov ah, 09h ; print implicit-length string
mov dx, OFFSET str2
int 21h
mov ah, 04ch ; exit
int 21h
alterChar:
mov al, 'o'
;jmp doneAlteration
stosb
jmp copyStr
end main