2017-06-03 231 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