组装:我的线性搜索代码有问题
Posted
技术标签:
【中文标题】组装:我的线性搜索代码有问题【英文标题】:Assembly: troubles with my linear search code 【发布时间】:2017-04-03 02:09:55 【问题描述】:对于分配,我必须完成程序的代码,该程序使用循环将每个数组元素与通过用户输入提供的目标值进行比较。例如,当程序要求我输入一个数字并且我输入数字 6 时,它应该给我这个列表中的第六个数字。 '7','3','2','1','0','5','6','4','8','9'
我输入了 cmets 让我输入的内容,但是当我尝试编译它时,我不断收到此错误。
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
【问题讨论】:
cmp al, target
将目标地址与 AL 进行比较。您想比较target
的内容,所以它应该是cmp al, [target]
。此错误会导致您收到的链接器错误。同样,我认为您的意思不是je targetlocation
(这是数据部分中的标签)。也许你的意思是je found
? (这就是评论所暗示的)
@MichaelPetch 它可以工作,但最初当我将目标位置更改为“je found”时,输出告诉我“找不到目标值”。将其更改为“找到 jmp”,但这只是说“在索引 0 处找到目标值”。任何想法如何解决这一问题?我尝试了不同的跳跃功能,但它们没有给我想要的。
【参考方案1】:
假设您正在为 x86 架构编写代码,问题是 getNextElement
中的 je
指令。 je
指令是短跳转,它只需要相对地址作为参数,不能用于间接跳转。这里可以看看je
和jmp
指令的区别:
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
【讨论】:
是的,如果评论有帮助,请不要忘记投票。以上是关于组装:我的线性搜索代码有问题的主要内容,如果未能解决你的问题,请参考以下文章