2017-11-17 1 views
2

yasm을 사용하여 아래 코드를 조합하려고합니다. yasm이 "오류 : 피연산자 2의 크기가 올바르지 않습니다."라는 오류를보고하는 '여기'주석을 달았습니다. 이 오류가 발생하는 이유는 무엇입니까? 양 피연산자는 동일한 크기 일 필요하기 때문에 대부분의 지시yasm movsx, movsxd 피연산자 2의 크기가 유효하지 않습니다.

segment .data 
    a db 25 
    b dw 0xffff 
    c dd 3456 
    d dq -14 

segment .bss 
    res resq 1 

segment .text 
    global _start 

_start: 
    movsx rax, [a] ; here 
    movsx rbx, [b] ; here 
    movsxd rcx, [c] ; here 
    mov rdx, [d] 
    add rcx, rdx 
    add rbx, rcx 
    add rax, rbx 
    mov [res], rax 
    ret 
+0

크기를 지정해야합니다. 'movsx rax, byte [a]' – Jester

+1

당신이 내 문제를 해결했다면, 원하면 대답으로 게시해야합니다. –

답변

1

은 레지스터 오퍼랜드의 폭은, 상기 메모리 연산의 폭을 의미한다. 예 : mov rdx, [d]은 사용자가 64 비트 레지스터를 사용했기 때문에 mov rdx, qword [d]을 의미합니다.

그러나 같은 movsx/movzx 니모닉 바이트 소스와 단어 소스 옵 코드에 사용되는, 그래서 소스가 레지스터 (같은이 movzx eax, cl) 경우를 제외하고는 모호합니다.

movsx/movzx 메모리 소스는 항상 명시 적으로 지정된 메모리 피연산자의 너비가 필요합니다.

니모닉은 32 비트 원본 크기를 나타냅니다. movsxd rcx, [c]은 NASM과 조립되지만 YASM에서는 분명히 조립되지 않습니다. byte, word 또는 qword을 허용하지 않으며 movsx rcx, dword [c]을 수락하지 않더라도 (즉, 32 비트 소스 피연산자에 대해서는 movsxd 니모닉이 필요합니다) YASM은 dword을 작성해야합니다.

NASM에서 movsx rcx, dword [c]movsxd으로 어셈블되지만, movsxd rcx, word [c]은 여전히 ​​거부됩니다. 즉 NASM에서 일반 movsx은 완전히 유연하지만 movsxd은 여전히 ​​견고합니다. 부하의 폭을 사람의 이익을 위해 명시 적으로 만들려면 dword을 사용하는 것이 좋습니다. 대상의 폭이

movsx rax, byte [a] 
movsx rbx, word [b] 
movsxd rcx, dword [c] 

참고 명령어의 "오퍼랜드 크기"(피연산자 크기 접두사에 의해 결정은 16 비트 확인하거나 REX.W = 1은 64 비트를 만들기 위해) 것을 movsx/movzx입니다. 소스 크기가 다르면 다른 opcode를 사용합니다. 경우


그것은 분명하지, 32-bit mov already zero-extends to 64-bit implicitly 때문에 더 movzxd 없다입니다. movsxd eax, ecx은 인코딩 할 수 있지만 권장되지는 않습니다 (대신 mov을 사용하십시오).

T 문법에서 다른 소스 - 너비는 movsb 또는 movsw과 같이 다른 니모닉을가집니다. 대상 크기는 평소와 같이 접미사이므로 명시 적으로 movsbq (%rsi), %rax을 작성하거나 %rax에서 대상 크기를 유추 할 수 있도록 movsb (%rsi), %rax을 작성할 수 있습니다. 소스 코드에 대한


다른 물건 :

NASM/YASM는 대신 sectionsegment 키워드를 사용하는 것을 허용하지만, 정말 당신은 ELF 섹션 이름이 아니라 실행 세그먼트 이름을 제공하고 있습니다. 또한 읽기 전용 데이터는 section .rodata (텍스트 세그먼트의 일부로 연결됨)에 넣을 수 있습니다. What's the difference of section and segment in ELF file format.

ret부터 _start까지는 입력 할 수 없습니다. 기능이 아닙니다. ELF 진입 점입니다.스택의 첫 번째 것은 유효한 반환 주소가 아닌 argc입니다. 정상적으로 종료 할 때 사용 :

xor edi,edi 
mov eax, 231 
syscall   ; sys_exit_group(0) 

링크에 더 유용한 가이드 (그리고 하단에 디버깅 팁)의 태그 위키를 참조하십시오.

관련 문제