2017-04-03 1 views
1

과제에 대해 루프를 사용하여 각 입력 요소를 사용자 입력을 통해 제공되는 목표 값과 비교하는 프로그램의 코드를 마무리해야합니다. 예를 들어, 프로그램에서 숫자를 입력하라는 메시지가 나타나고 숫자 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 

이것은 컴파일하는 데 사용 된 웹 사이트입니다. 어떤 도움이라도 대단히 감사하겠습니다. 당신은 x86 아키텍처에 대한 문제를 코드를 작성하고 있다고 가정

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

+0

'cmp al, target'은 target의 주소와 _AL_을 비교합니다. 'target'에있는 것을 비교하기 위해서'cmp al, [target]'이어야합니다. 이 오류로 인해 링커 오류가 발생합니다. 또한 나는 당신이'je targetlocation'을 의미하는 것 같지 않습니다. (이것은 데이터 섹션의 레이블입니다). 어쩌면 당신은'je found '를 의미했을까요? (코멘트가 의미하는 것입니다.) –

+0

@MichaelPetch 원래 목표 위치를 "je found"로 변경했을 때 작동하지만 출력에서 ​​"목표 값을 찾을 수 없습니다." "jmp found"로 변경했지만 "목표 값은 인덱스 0에서 발견되었습니다." 어떤 아이디어가 이것을 고치는 방법? 나는 다른 점프 fucntions를 시도했다. 그러나 그들은 내가 원하는 것을 나에게주지 않는다. – iwasherenotyou

답변

-1

getNextElement에서 je 명령어입니다. je 명령은 짧은 점프이며 상대 주소를 매개 변수로만 예상하며 간접 점프를 만드는 데 사용할 수 없습니다. 여기

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

당신이 메모리에 al 이동하고 있으며 의견은 말한다 :

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

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

추가를 : 여기 jejmp 지침 사이의 차이를 볼 수 있습니다 반대말. 문제가 발생하면 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 
+0

네, 의견이 도움이된다면, 투표를 올려주세요. – nopasara