2017-06-03 197 views
2

如何在汇编程序中创建字符串数组并使用它们?从字符串数组中打印一个字符串

我尝试:

arrayOfWords BYTE "BICYCLE", "CANOE", "SCATEBOARD", "OFFSIDE", "TENNIS" 

后,我想打印第二个字,但它不工作

mov edx, offset arrayOfWords[2] 
    call WriteString 

但他打印了我全部的世界。

+1

如果您使用Kip Irvine的库,请用[irvine32]和[masm]标记问题。 – rkhb

+0

irvine http://programming.msjc.edu/asm/help/index.html?page=source%2Fabout.htm – SakaSerbia

+0

然后点击“编辑”并添加到“标签”[masm]和[irvine32]下(不包括括号)。之后,你从我身上得到一些例子来复制和粘贴;-) – rkhb

回答

1

arrayOfWords不是一个数组,甚至不是一个变量。这只是一个标签,告诉汇编器它能找到什么东西,在这里是一堆字符。 Irvine的WriteString预期以空字符结尾的字符串作为字符串。有两种方法将字符串作为字符串数组来处理。

  1. 在内存中搜索所需字符串的正确地址。在每一个null开始一个新的字符串。

    INCLUDE Irvine32.inc 
    
    .DATA 
    manyWords BYTE "BICYCLE", 0 
        BYTE "CANOE", 0 
        BYTE "SCATEBOARD", 0 
        BYTE "OFFSIDE", 0 
        BYTE "TENNIS", 0 
        BYTE 0        ; End of list 
    len equ $ - manyWords 
    
    .CODE 
    main PROC 
    
        mov edx, 2       ; Index 
        call find_str      ; Returns EDI = pointer to string 
    
        mov edx, edi 
        call WriteString     ; Irvine32: Write astring pointed to by EDX 
    
        exit        ; Irvine32: ExitProcess 
    main ENDP 
    
    find_str PROC       ; ARG: EDX = index 
    
        lea edi, manyWords     ; Address of string list 
    
        mov ecx, len      ; Maximal number of bytes to scan 
        xor al, al       ; Scan for 0 
    
        @@: 
        sub edx, 1 
        jc done        ; No index left to scan = string found 
        repne scasb       ; Scan for AL 
        jmp @B        ; Next string 
    
        done: 
        ret 
    find_str ENDP       ; RESULT: EDI pointer to string[edx] 
    
    END main 
    
  2. 生成指针数组的字符串:

    INCLUDE Irvine32.inc 
    
    .DATA 
    wrd0 BYTE "BICYCLE", 0 
    wrd1 BYTE "CANOE", 0 
    wrd2 BYTE "SCATEBOARD", 0 
    wrd3 BYTE "OFFSIDE", 0 
    wrd4 BYTE "TENNIS", 0 
    
    pointers DWORD OFFSET wrd0, OFFSET wrd1, OFFSET wrd2, OFFSET wrd3, OFFSET wrd4 
    
    .CODE 
    main PROC 
    
        mov ecx, 2       ; Index 
        lea edx, [pointers + ecx * 4]  ; Address of pointers[index] 
        mov edx, [edx]      ; Address of string 
        call WriteString 
    
        exit        ; Irvine32: ExitProcess 
    main ENDP 
    
    END main 
    

顺便说一句:如在其它语言中,索引从0开始的第二个字符串将是索引= 1,则第三个索引= 2.

+0

'lea edi,manyWords' - >我如何在nasm或fasm中执行此操作? – Jodimoro

+0

@Jodimoro:NASM:'lea edi,[manyWords]'或'mov edi,manyWords'..我想在FASM里它是一样的。我不太确定,以及irvine32.lib在NASM或FASM中是如何工作的。无论如何,它在Linux中都不起作用。如果你问一个新的问题,我会努力;-) – rkhb

+0

为什么不''[]'?... – Jodimoro

2
arrayOfWords BYTE "BICYCLE", "CANOE", "SCATEBOARD", "OFFSIDE", "TENNIS" 

只是另一种方式编写

arrayOfWords BYTE "BICYCLECANOESCATEBOARDOFFSIDETENNIS" 

,这远不是阵列。
此外mov edx, offset arrayOfWords[2]不是数组索引。
装配中的方括号用于表示addressing mode,而不是数组索引。
这就是为什么我不能停下来强调出 使用语法<symbol>[<displacement>](您arrayOfWords[2]) - 这是写[<symbol> + <displacement>](你的情况[arrayOfWords + 2])非常愚蠢和混乱的方式。

你可以看到mov edx, OFFSET [arrayOfWords + 2](在我看来更清晰写成mov edx, OFFSET arrayOfWords + 2由于指令不访问任何内存)只是加载edxÇ字符的BICYCLE地址(第三字符大串)。

MASM有很多高级机器,我从来没有打扰过学习,但在脚注中快速浏览手册后,似乎没有对数组的高级支持。
这是一件好事,我们可以使用更清洁的组件。

字符串数组不是连续的字符串块,它是连续的指针到字符串块。
字符串可以在任何地方。

arrayOfWords DWORD OFFSET strBicycle, 
        OFFSET strCanoe, 
        OFFSET strSkateboard, 
        OFFSET strOffside, 
        OFFSET strTennis 

strBicycle BYTE "BICYCLE",0 
strCanoe  BYTE "CANOE", 0 
strSkateboard BYTE "SKATEBOARD", 0 
strOffside BYTE "OFFSIDE", 0 
strTennis  BYTE "TENNIS", 0 

请记住:数组的好处是恒定的访问时间;如果将字符串放在一起,我们会得到更紧凑的数据结构,但没有固定的访问时间,因为无法知道字符串的起始位置,只能扫描整个事物。
随着指针我们有不断的访问时间,一般来说,我们需要一个数组的所有元素是齐次的,就像指针一样。

要加载第i 串的阵列中,我们简单地读出的第i指针的地址。
假设ecx然后

mov edx, DWORD PTR [arrayOfWords + ecx*4] 
call writeString 

因为每个指针是四个字节。

如果你想读的字符串的字节Ĵ然后,在ecx假设Ĵebx

mov esi, DWORD PTR [arrayOfWords + ecx*4] 
mov al, BYTE PTR [esi + ebx] 

使用的寄存器是任意的。


尽管什么微软在其MASM 6.1 manual写道:

引用数组
阵列中的每个元素与索引编号引用,以零开头。数组索引出现在数组名称后的括号内,如

array[9]

汇编语言指数从高层次的语言,在那里索引号 总是对应于元素的位置的索引不同。例如,在C中,无论每个元素是1个字节还是8个字节,数组[9]都会引用数组的第012个元素。 在汇编语言中,元素的索引是指元素和数组开始之间的字节数。

从零开始计数。

+0

非常感谢。这是我读过的最好的解释。:)新的我会尽力解决我的问题。我正在为我的大学项目制作hang子手游戏。它的30%是我的标志。 – SakaSerbia