문제

나는 어셈블리를 배우려고 노력하고 있습니다 (그래서 나와 함께 참아주세요).이 라인에서 컴파일 오류를 받고 있습니다.

mov byte [t_last], [t_cur]

오류는입니다

error: invalid combination of opcode and operands

이 오류의 원인은 단순히 MOV 명령이 두 메모리 주소 사이를 이동하는 것이 불가능하지만 반 시간의 인터넷 검색과 나는 이것을 확인할 수 없었다고 생각합니다. 이것이 사실입니까?

또한 내가 옳다고 가정하면 메모리 복사를위한 중간 지점으로 레지스터를 사용해야한다는 의미입니다.

mov cl, [t_cur]
mov [t_last], cl

권장되는 레지스터는 무엇입니까 (또는 스택을 대신 사용해야합니까)?

도움이 되었습니까?

해결책

당신의 의심은 정확합니다. 기억에서 기억으로 이동할 수 없습니다.

모든 일반 목적 등록부는 할 것입니다. 내부에 무엇이 있는지 확실하지 않은 경우 레지스터를 푸시하고 한 번 다시 복원해야합니다.

다른 팁

16 비트로 정말 간단합니다. 다음을 수행하십시오.

     push     di
     push     si
     push     cx
     mov      cx,(number of bytes to move)
     lea      di,(destination address)
     lea      si,(source address)
     rep      movsb
     pop      cx
     pop      si
     pop      di

참고 : 레지스터의 내용을 저장 해야하는 경우 푸시 및 팝은 반드시 필요합니다.

메모리에서 메모리로 데이터를 이동하는 것의 MOVS 명령도 있습니다.

MOV SI, OFFSET variable1
MOV DI, OFFSET variable2
MOVS

기술적으로 메모리에서 메모리로 이동하는 것이 가능합니다.

사용해보십시오 움직입니다 (문자열 이동) 및 설정 e] si 그리고 E] di, 바이트, 단어 등을 전송할 것인지에 따라

mov si, t_cur    ; Load SI with address of 't_cur'
mov di, t_last   ; Load DI with address of 't_last'
movsb            ; Move byte from [SI] to [DI]

; Some dummy data
t_cur    db 0x9a ; DB tells NASM that we want to declare a byte
t_last   db 0x7f ; (See above)

임시 레지스터가 하나 인 일반로드 + 저장소를 사용하는 것보다 효율적이지 않지만 단일 명령으로 실제 사본을 수행합니다.

방법은 다음과 같습니다 움직입니다 사용해야하며 작동 방식 :https://www.felixcloutier.com/x86/movs:movsb:movsw:movsd:movsq

일반적으로 a와 함께 사용됩니다 rep 단일 요소가 아닌 블록 카피의 접두사. (현대 CPU는 상당히 효율적인 마이크로 코드를 가지고 있습니다 rep movsb AVX 벡터로드/스토어 지침을 사용하여 루프 속도에 가깝습니다.)

맞습니다. x86 머신 코드는 두 가지로 명령을 인코딩 할 수 없습니다. 명백한 메모리 피연산자 (임의 주소가 지정된 주소 [])

권장 레지스터는 무엇입니까?

저장/복원 할 필요가없는 레지스터.

모든 주류 32 비트 및 64 비트 전화 규칙에서 EAX, ECX 및 EDX는 콜 클로버링되므로 Al, CL 및 DL이 좋은 선택입니다. 바이트 또는 단어 사본의 경우 일반적으로 movzx 32 비트 레지스터, 8 비트 또는 16 비트 매장에로드하십시오. 이것은 레지스터의 이전 값에 대한 잘못된 의존성을 피합니다. 좁은 16 또는 8 비트 만 사용하십시오 mov 적극적으로로드하십시오 원하다 다른 값의 낮은 비트로 합쳐지기 위해. x86 movzx 팔과 같은 지침의 아날로그입니다 ldrb.

    movzx   ecx,  byte [rdi]       ; load CL, zero-extending into RCX
    mov    [rdi+10], cl

64 비트 모드에서 SIL, DIL, R8B, R9B 등도 훌륭한 선택이지만 매장의 기계 코드에 Rex 접두사가 필요하므로 피해야 할 작은 코드 크기의 이유가 있습니다.

다음 링크를 읽고 이해하지 못하고 허위 종속성 또는 부분 등록 마구간을 읽지 않는 한 일반적으로 AH, BH, CH 또는 DH를 쓰지 마십시오. 코드에서 문제가되지 않거나 전혀 발생하지 않습니다. .


(또는 스택을 대신 사용해야합니까)?

우선, 단일 바이트를 전혀 밀 수 없으므로 스택에서 바이트 하중 / 바이트 상점을 수행 할 수있는 방법이 없습니다. 단어, dword 또는 qword (CPU 모드에 따라) push [src] / pop [dst], 그러나 레지스터를 통해 복사하는 것보다 훨씬 느립니다. 데이터를 최종 대상에서 읽기 전에 추가 상점/새로 고침 저장소 대기 시간을 소개하고 더 많은 UOP를 사용합니다.

스택 어딘가에 ~이다 원하는 목적지와 해당 로컬 변수를 레지스터로 최적화 할 수 없습니다. push [src] 거기에 복사하고 스택 공간을 할당하는 것이 좋습니다.

보다 https://agner.org/optimize/ 및 기타 X86 성능 링크 x86 태그 위키

"메모리 배리어"에 대해 논의하고 싶습니다. C 코드에서

a = b;//Take data from b and puts it in a

조립됩니다

mov %eax, b # suppose %eax is used as the temp
mov a, %eax

시스템은 과제의 원자력을 보장 할 수 없습니다. 그것이 우리가 RMB가 필요한 이유입니다 (읽기 장벽)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top