Assembly 访问阵列';汇编语言(windows)中的s元素

Assembly 访问阵列';汇编语言(windows)中的s元素,assembly,Assembly,我在汇编语言中遇到了一个问题,我无法访问数组的元素。。。假设一个数组包含星期天。。。像太阳、周一、周二、周三。。。。我必须访问数组的第二个索引。。。如何实现这一点?汇编中的索引与C/C++基本相同,只是有一个区别:您必须知道数据元素的大小 例如,要循环汇编中的字节数组(或字符串中的字符),可以执行以下操作: mov eax, 0 mov ecx, 0 loop_start: cmp ecx, ARRAY_LENGTH jge loop_end add eax, BYTE PTR

我在汇编语言中遇到了一个问题,我无法访问数组的元素。。。假设一个数组包含星期天。。。像太阳、周一、周二、周三。。。。我必须访问数组的第二个索引。。。如何实现这一点?

汇编中的索引与C/C++基本相同,只是有一个区别:您必须知道数据元素的大小

例如,要循环汇编中的字节数组(或字符串中的字符),可以执行以下操作:

mov eax, 0
mov ecx, 0

loop_start:
  cmp ecx, ARRAY_LENGTH
  jge loop_end

  add eax, BYTE PTR myArray[ecx]

  add ecx, 1
  jmp loop_start
loop_end:
如您所见,数组通过递增ecx(我将其用作计数器)一次循环通过一个元素。每个元素都添加到eax中,eax包含循环末尾的和。请注意,在引用数组时,我必须添加“BYTE PTR”来告诉汇编程序我使用的数据类型

现在看一下这段代码,它对DWORD数据(4字节)执行相同的操作:

只有两件事改变了:我不再需要在这里使用“BYTE PTR”,因为除非另有说明,否则汇编程序假定您在32位机器上使用32位数据类型;我还需要将数组的索引更改为“ecx*4”,因为数组中的每个元素都有4个字节长。32位机器上使用的大多数数据类型的大小都是32位的,因此后面的示例更常见

要回答您的特定问题,这里有一种方法可以循环遍历字符串数组并显示它们:

.data
  sunday    db "Sun",0
  monday    db "Mon",0
  tuesday   db "Tues",0
  wednesday db "Wed",0
  thursday  db "Thurs",0
  friday    db "Fri",0
  saturday  db "Sat",0

  daysOfWeek dd OFFSET sunday, OFFSET monday, OFFSET tuesday OFFSET wednesday
             dd OFFSET thursday, OFFSET friday, OFFSET saturday

.code
mov ecx, 0

loop_start:
  cmp ecx, 7
  jge loop_end

  mov eax, daysOfWeek[ecx*4]
  ; eax now contains the pointer to the
  ; next element in the array of days

  add ecx, 1
  jmp loop_start
loop_end:

因为32位机器上的指针是32位宽的,所以像第二个例子中的DWORD一样对待它们。

汇编语言适用于哪个平台?Z80?6502? 80x86?680x0?发布迄今为止您为此编写的所有代码,然后这里的人可以帮助您使其工作。@Guffa-考虑到它说的是windows,可能是x86汇编,顺便说一句,这是吹毛求疵,但您可以通过向下而不是向上计数来简化汇编:
mov ecx,ARRAY_LENGTH;循环_开始:添加eax,字节PTR myArray[ecx];dec-ecx;我不知道他将如何使用字符串。如果他打算把它们输出到屏幕上,那么以相反的顺序看到它们会很奇怪。过早优化是万恶之源。
addeax,BYTE-PTR-myArray[ecx]
无法组装。在添加到32位寄存器之前,需要一个单独的
movzx
movsx
指令进行零或符号扩展。另外,[asm中惯用的循环结构在底部有条件分支](,所以这些例子看起来很痛苦。除非另有说明,否则汇编程序假设您在32位机器上使用32位数据类型。不,汇编程序从寄存器推断操作数大小。或者使用MASM,如果您在寻址模式中使用符号名,也可以从标签dd 1,2,3中的db/dw/dd/dq推断操作数大小。@Peter Cordes“添加eax,内存地址”与“添加eax,字节PTR内存地址”相同“因为我使用了相同的寄存器?显然不是。我的观点是,而且我不认为这是不清楚的,在我的示例中,当操作数在32位机器上为32位时,您不需要指定操作数的大小。但是,通过显式说明其大小,您可以清楚地使用16位或8位操作数。
.data
  sunday    db "Sun",0
  monday    db "Mon",0
  tuesday   db "Tues",0
  wednesday db "Wed",0
  thursday  db "Thurs",0
  friday    db "Fri",0
  saturday  db "Sat",0

  daysOfWeek dd OFFSET sunday, OFFSET monday, OFFSET tuesday OFFSET wednesday
             dd OFFSET thursday, OFFSET friday, OFFSET saturday

.code
mov ecx, 0

loop_start:
  cmp ecx, 7
  jge loop_end

  mov eax, daysOfWeek[ecx*4]
  ; eax now contains the pointer to the
  ; next element in the array of days

  add ecx, 1
  jmp loop_start
loop_end: