从字符串数组中打印一个字符串
如何在汇编程序中创建字符串数组并使用它们?从字符串数组中打印一个字符串
我尝试:
arrayOfWords BYTE "BICYCLE", "CANOE", "SCATEBOARD", "OFFSIDE", "TENNIS"
后,我想打印第二个字,但它不工作
mov edx, offset arrayOfWords[2]
call WriteString
但他打印了我全部的世界。
arrayOfWords
不是一个数组,甚至不是一个变量。这只是一个标签,告诉汇编器它能找到什么东西,在这里是一堆字符。 Irvine的WriteString
预期以空字符结尾的字符串作为字符串。有两种方法将字符串作为字符串数组来处理。
-
在内存中搜索所需字符串的正确地址。在每一个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
-
生成指针数组的字符串:
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.
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个元素。 在汇编语言中,元素的索引是指元素和数组开始之间的字节数。
从零开始计数。
非常感谢。这是我读过的最好的解释。:)新的我会尽力解决我的问题。我正在为我的大学项目制作hang子手游戏。它的30%是我的标志。 – SakaSerbia
如果您使用Kip Irvine的库,请用[irvine32]和[masm]标记问题。 – rkhb
irvine http://programming.msjc.edu/asm/help/index.html?page=source%2Fabout.htm – SakaSerbia
然后点击“编辑”并添加到“标签”[masm]和[irvine32]下(不包括括号)。之后,你从我身上得到一些例子来复制和粘贴;-) – rkhb