2017-05-01 1 views
0

워드 배열에서 가장 큰 값을 반환하는 프로 시저를 작성하려고했습니다. 로컬 변수를 here으로 표시된 규칙에 따라 할당했습니다. 하지만 지역 변수에 값을 이동하려고 할 때 그것이 나에게이 오류 제공 : 어떤 도움을 크게 감상 할 수Nasm 어셈블리. 값을 스택의 로컬 변수로 옮길 수 없습니다.

greatest: 

    push ebp 
    mov ebp, esp 
         ;allocate local variables here 
    sub esp, 4 
         ;push stuff 
    push esi 

    mov ecx, [ebp+12] ;size of the array 
    mov eax, [ebp+8] ;offset of the array 
    mov esi, 0   ;counter for accessing elements 
    mov ebp-4, eax  ;error here 
l1: 
    push ecx 
    mov ecx, [eax + 2*esi] ;get the variable 
    cmp [ecx], [ebp-4]  ;compare values 
    jb if_2     
    mov ebp-4, ecx  ;error here 
if_2: 
    inc esi 
    pop ecx 
    loop l1 

    mov eax, [ebp-4] 

    pop esi 
    mov esp, ebp 
    pop ebp 
    ret 

:

+3

'cmp [ecx], [ebp-4]'mem과 mem를 비교할 수 없습니다 –

+0

@Alexander Zhak하지만 레지스트리에 있습니다. 컴파일러는 신경 쓰지 않는 것 같습니다. 나는 주어진 링크에서 MASM이 사용되고 'mov ebp-4, eax'가 잘 작동한다는 것을 알고 싶다. NASM에서는 그렇게 보이지 않습니다. 메모리 및 값 주소 지정을위한 구문과 관련이 있습니다. –

+0

MASM은'mov ebp-4, eax'를 모으기를 거부합니다. "* 오류 A2032 : 레지스터 * 사용이 잘못되었습니다." – rkhb

답변

0
: 여기

invalid combination of opcode and operands

내 코드입니다

주석에서 지적한 바와 같이 코드의 문제는 주위의 것의 차이와 []이 아닌 것입니다.

nasm으로 표시된 줄에 괄호가 없습니다. ebp - 4은 데이터를 저장할 메모리의 위치이므로 대괄호로 묶어야합니다.

다른 문제는 cmp [ecx], [ebp - 4]입니다. 이것은 메모리에있는 두 개의 다른 아이템을 비교하려고 시도하기 때문에 컴파일되지 않을 것입니다. 위치는 ecxebp - 4입니다. 두 개의 다른 메모리를 가지고는 할 수 없습니다. 적어도 하나는 레지스터/상수 여야합니다.

그러나 이것은 실제로 당신이 어쨌든하고 싶어하는 것이 아닙니다. ecx값이이고, 위치는이 아니므로 실제로는 cmp ecx, [ebp - 4]이 필요합니다. 이 말이 맞습니다.

이러한 사항을 변경하면 코드가 컴파일됩니다. 그러나 올바르게 실행되지는 않습니다. nasm이 마음에 들지만 괄호와 대괄호는 여전히 문제가 있습니다.

지난 번 내가 본 마지막 문제는 mov [ebp - 4], eax (이전) 줄입니다. eax에는 목록의 오프셋 (주소)과 첫 번째 요소의 주소가 포함되어 있지만 요소 자체는 포함되어 있지 않으므로 대괄호로 묶어야합니다.

그러나 단지 mov [ebp - 4], [eax]으로 작성하면 이전과 비슷한 오류가 발생합니다. nasm은 두 개의 메모리를 가질 수 없기 때문에 큰 소리로 외칩니다.

임시 저장소로 레지스터 (예 : esi)를 사용하여 문제를 해결할 수 있습니다. (우리는 어쨌든 그것을 덮어 쓰기를하고 있기 때문에 나는 esi을 선택했다, 그래서 우리는 스택에 저장할 필요가 없습니다.) 그래서이된다 : 그래서

mov esi, [eax] 
mov [ebp-4], esi 
mov esi, 0  ; moved this line from above so it's still 0 at the end 

전부, 이것은이되는 변화 :

greatest: 

    push ebp 
    mov ebp, esp 
         ;allocate local variables here 
    sub esp, 4 
         ;push stuff 
    push esi 

    mov ecx, [ebp+12] ;size of the array 
    mov eax, [ebp+8] ;offset of the array 
    mov esi, [eax]  ;store in esi temporarily 
    mov [ebp-4], esi ;now we can move it to the local variable 
    mov esi, 0   ;counter for accessing elements 

l1: 
    push ecx 
    mov ecx, [eax + 2*esi] ;get the item from the list 
    cmp ecx, [ebp-4]  ;compare values 
    jb if_2     
    mov [ebp-4], ecx  
if_2: 
    inc esi 
    pop ecx 
    loop l1 

    mov eax, [ebp-4] 

    pop esi 
    mov esp, ebp 
    pop ebp 
    ret 
+0

고마워요! 그게 정말 메모리/레지스트리 처리에 대한 빛을 비춰줍니다. 나는 MASM과 NASM 메모리의 다른 신택스를 혼동하여 실제로 무엇이 저장되어 있는지 잊어 버렸다. 대답은 매우 유용합니다. 다시 한 번 감사드립니다! –

관련 문제