汇编:我的线性搜索代码有问题

Assembly: troubles with my linear search code

对于一项作业,我必须完成一个程序的代码,该程序使用循环将每个数组元素与通过用户输入提供的目标值进行比较。因此,例如,当程序要求我键入一个数字,而我键入数字 6 时,它应该会给出此列表中的第六个数字。 '7','3','2','1','0','5','6','4','8','9'

我输入了评论告诉我输入的内容,但是当我尝试编译它时,我总是收到这个错误。

main.o: In function `getNextElement':
main.asm:(.text+0x92): relocation truncated to fit: R_386_8 against '.data' 

谁能告诉我我做错了什么?

    ;;;;;;;;;;;;;;;;;;;;    MACRO DEFINITIONS   ;;;;;;;;;;;;;;;;;;;;
; A macro with two parameters
; Implements the write system call
    %macro writestring 2
        mov eax, 4  ;sys_write system call number
        mov ebx, 1  ;file descriptor std_out
        mov ecx, %1 ;message to write from parameter 1
        mov edx, %2 ;message length from parameter 2
        int 0x80
    %endmacro
; A macro with two parameters
; Implements the sys_read call
    %macro read_string 2
        mov eax, 3  ;sys_write system call number
        mov ebx, 2  ;file descriptor std_in
        mov ecx, %1 ;variable/array to hold data, pass by reference in param 1
        mov edx, %2 ;number of bytes to read passed by value in param 2
        int 0x80
    %endmacro

;;;;;;;;;;;;;;;;;;;;    DATA SEGMENT    ;;;;;;;;;;;;;;;;;;;;
section .data
msg1 db 'Here are the elements: '
lenmsg1 equ $-msg1
msg2 db 'Enter a number to search for: '
lenmsg2 equ $-msg2
msg3 db 'The target value was found at index '
lenmsg3 equ $-msg3
msg4 db 'The target value was NOT found...',0x0a, 0x0d
lenmsg4 equ $-msg4
asciinums db '7','3','2','1','0','5','6','4','8','9'
lenasciinums equ $-asciinums
crlf db 0x0d, 0x0a
lencrlf equ $ - crlf                
target db 0x00
targetlocation db 0x30

section .text
    global _start
_start:
    writestring msg1, lenmsg1
    writestring asciinums, lenasciinums
    writestring crlf, lencrlf
    writestring msg2, lenmsg2
    read_string target, 1
    writestring crlf, lencrlf
    mov eax, asciinums  ;eax holds base address
    mov ecx, 0          ;ecx is index register
getNextElement:
    mov [eax+ecx], al   ;copy value from asciinums into an 8-bit register
    cmp al, target      ;compare the 8-bit register to target value
    je  targetlocation  ;jump if equal to the found label
    inc ecx             ;increment index register
    cmp ecx, 10         ;compare index register to decimal 10
    jne getNextElement  ;if index register not equal to 10 go to getNextElement

    writestring msg4, lenmsg4
    jmp terminate
found:
    add [targetlocation], ecx
    writestring msg3, lenmsg3
    writestring targetlocation, 1
    writestring crlf, lencrlf
terminate:
    mov eax, 1          ;terminate program
    int 0x80

我也知道问题出在这段代码上。

    mov eax, asciinums  ;eax holds base address
    mov ecx, 0          ;ecx is index register
getNextElement:
    mov [eax+ecx], al   ;copy value from asciinums into an 8-bit register
    cmp al, target      ;compare the 8-bit register to target value
    je  targetlocation  ;jump if equal to the found label
    inc ecx             ;increment index register
    cmp ecx, 10         ;compare index register to decimal 10
    jne getNextElement  ;if index register not equal to 10 go to getNextElement

这是我用来编译的网站。任何帮助将不胜感激。

https://www.tutorialspoint.com/compile_assembly_online.php

假设您正在为 x86 体系结构编写代码,问题是 getNextElement 中的 je 指令。 je 指令是短跳转,只需要相对地址作为参数,不能用于间接跳转。这里可以看看jejmp指令的区别:

http://x86.renejeschke.de/html/file_module_x86_id_146.html

http://x86.renejeschke.de/html/file_module_x86_id_147.html

已添加:

mov [eax+ecx], al ;copy value from asciinums into an 8-bit register

此处您将 ​​al 移动到内存中,评论则相反。修复它,使用 je found 并重试。

已添加:

还有一个: mov [eax+ecx], al ;copy value from asciinums into an 8-bit register 在这里,您通过将数据加载到 al 来破坏 eax 寄存器。在下一个循环中,您将从内存中获取垃圾。

已检查,在修复所有提到的错误后,它运行良好。

;;;;;;;;;;;;;;;;;;;;    MACRO DEFINITIONS   ;;;;;;;;;;;;;;;;;;;;
; A macro with two parameters
; Implements the write system call
    %macro writestring 2
        mov eax, 4  ;sys_write system call number
        mov ebx, 1  ;file descriptor std_out
        mov ecx, %1 ;message to write from parameter 1
        mov edx, %2 ;message length from parameter 2
        int 0x80
    %endmacro
; A macro with two parameters
; Implements the sys_read call
    %macro read_string 2
        mov eax, 3  ;sys_write system call number
        mov ebx, 2  ;file descriptor std_in
        mov ecx, %1 ;variable/array to hold data, pass by reference in param 1
        mov edx, %2 ;number of bytes to read passed by value in param 2
        int 0x80
    %endmacro

;;;;;;;;;;;;;;;;;;;;    DATA SEGMENT    ;;;;;;;;;;;;;;;;;;;;
section .data
msg1 db 'Here are the elements: '
lenmsg1 equ $-msg1
msg2 db 'Enter a number to search for: '
lenmsg2 equ $-msg2
msg3 db 'The target value was found at index '
lenmsg3 equ $-msg3
msg4 db 'The target value was NOT found...',0x0a, 0x0d
lenmsg4 equ $-msg4
asciinums db '7','3','2','1','0','5','6','4','8','9'
lenasciinums equ $-asciinums
crlf db 0x0d, 0x0a
lencrlf equ $ - crlf                
target db 0x00
targetlocation db 0x30

section .text
    global _start
_start:
    writestring msg1, lenmsg1
    writestring asciinums, lenasciinums
    writestring crlf, lencrlf
    writestring msg2, lenmsg2
    read_string target, 1
    writestring crlf, lencrlf
    mov eax, asciinums  ;eax holds base address
    mov ecx, 0          ;ecx is index register
getNextElement:
    mov bl, [eax+ecx]   ;copy value from asciinums into an 8-bit register
    cmp bl, [target]    ;compare the 8-bit register to target value
    je  found           ;jump if equal to the found label
    inc ecx             ;increment index register
    cmp ecx, 10         ;compare index register to decimal 10
    jne getNextElement  ;if index register not equal to 10 go to getNextElement

    writestring msg4, lenmsg4
    jmp terminate
found:
    add [targetlocation], ecx
    writestring msg3, lenmsg3
    writestring targetlocation, 1
    writestring crlf, lencrlf
terminate:
    mov eax, 1          ;terminate program
    int 0x80