如何在emu8086中使用字符串

时间:2016-11-13 16:08:39

标签: assembly emulation emu8086

我需要emu8086中的字符串帮助。我初始化了一个字符串:

str1 db "0neWord"

我有一个空字符串:

str2 db ?

现在我需要检查str1中的所有字母并复制到str2,但如果str1中的字母为0,我需要将其替换为O.如果不是,我需要复制这封信。

我该怎么做?

2 个答案:

答案 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 

LODSB Instruction您可以从here

了解有关字符串说明的详情

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