【问题标题】:invalid char '&' manipulating variables in memory无效的 char '&' 操作内存中的变量
【发布时间】:2016-04-09 14:13:32
【问题描述】:

我想从数组中计算最大值。我只使用了寄存器,但现在我在处理内存中的变量时遇到了麻烦。一开始我想让第一个数字成为最大值。我做了movl array(, %edi, 4), &max 它给出了错误,无效的字符'&'。正确的方法是什么? decl &n 指令也有类似的问题。

在代码中,我使用 %edi 作为索引,使用 %eax 作为当前值。

.data
    array:
        .int 31, 9, 42, 18, 40
    n:
        .int 5
    max:
        .int 0

.text
.globl _start

_start:
    movl $0, %edi
    movl array(, %edi, 4), &max
start_loop:
    incl %edi
    decl &n
    cmpl $0, n
    je exit_loop
    movl array(, %edi, 4), %eax
    cmpl max, %eax
    jle start_loop
    movl %eax, &max
    jmp start_loop

exit_loop:
    movl $1, %eax
    movl &max, %ebx
    int $0x80

【问题讨论】:

  • 你想让那个神奇的&做什么?您不需要它来访问变量。
  • 您不使用& 来表示地址。 max标签的地址。您的第二个问题是 Intel x86 指令不能使用两个内存操作数。您必须使用中间寄存器将其分解为两条指令。
  • 我的意思是你必须分手的那一行是movl array(, %edi, 4), &max。一个例子是movl array(, %edi, 4), %eaxmovl %eax, max
  • cmpl $0, ndecl n 之后不是必需的,因为如果n 变为零,decl 将自动设置零标志,因此无需额外与零进行比较。跨度>
  • 嗯,通常是的。但也有例外。就像MOVS(B/W/D) 一样,它使用固定索引寄存器/指针 (ESI/EDI) 将数据从内存移动到内存,而不使用任何寄存器。

标签: assembly x86 gnu-assembler att


【解决方案1】:

我想从数组中计算最大值。

解决获取数组最大值问题的简单方法如下代码(复制数据序言):

_start:
    movl n, %ecx                ; %ecx is now equal to the array len
    lea array, %esi             ; %esi points to the beginning of the array
    xorl %edx, %edx             ; first maximum value is 0
start_loop:
    movl (%esi), %eax           ; get value from array to %eax
    cmpl %edx, %eax             ; is new value greater (or equal) to the current max?
    cmovge %eax, %edx           ; then replace it
    add $4, %esi                ; set pointer to next element of array
    loop start_loop             ; decrement %ecx and jump to label if not 0
exit_loop:
    movl $1, %eax               ; SYS_EXIT
    movl %edx, %ebx             ; copy max to 'exit status'
    int $0x80                   ; execute SYSCALL

【讨论】:

  • movl 数组,%esi 会将整数移动到 esi 吗?它让我感到困惑,因为数组是地址的标签。
  • 我真的不确定你想对我说什么。在上面的代码中,像movl array, %esi 这样的行甚至都不存在。我使用指令lea array, %esi%esi 分配给array 的地址。之后,我使用movl (%esi), %eax 访问应用间接寻址模式的数组的值。指令movl array, %esi 只会将array 的前四个字节移动到%esiarray 是一个标签,movl 从该标签移动 4 个字节到目的地)。
猜你喜欢
  • 1970-01-01
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 2021-01-24
  • 2023-02-22
  • 1970-01-01
相关资源
最近更新 更多