수색…


무조건 점프

jmp a_label                      ;Jump to a_label
jmp bx                           ;Jump to address in BX
jmp WORD [aPointer]              ;Jump to address in aPointer
jmp 7c0h:0000h                   ;Jump to segment 7c0h and offset 0000h
jmp FAR WORD [aFarPointer]       ;Jump to segment:offset in aFarPointer

상대 근처 점프

jmp a_label 은 다음과 같습니다.

  • 가까운
    대상 논리 주소 의 오프셋 부분 만 지정합니다. 세그먼트는 CS 라고 가정합니다.
  • 상대적인
    명령어 의미 은 다음 명령 주소 또는 IP = IP + rel 에서 점프 rel 바이트 1 앞으로입니다.

명령어는 EB <rel8> 또는 EB <rel16/32> 로 인코딩되며, 어셈블러는 가장 적합한 형식을 선택하며 일반적으로 더 짧은 형식을 선호합니다.
예를 들어 NASM jmp SHORT a_label , jmp WORD a_labeljmp DWORD a_label 어셈블러 별 오버라이드가 가능합니다.

절대 가까운 간접 점프

jmp bxjmp WORD [aPointer] 는 다음과 같습니다.

  • 가까운
    목적지의 논리 주소의 오프셋 부분 만 지정합니다. 세그먼트는 CS 라고 가정합니다.
  • 절대 간접
    명령의 의미는 reg 또는 mem 또는 IP = reg , IP = mem 의 주소로 점프합니다.

명령은 FF /4 로 인코딩되며, 메모리 간접적으로 피연산자의 크기는 다른 메모리 액세스마다 결정됩니다.

절대 멀리뛰기

jmp 7c0h:0000h :

  • 멀리
    논리적 주소의 두 부분 인 세그먼트와 오프셋을 지정합니다.

  • absolute 명령의 의미는 주소 세그먼트 (offset 또는 CS = segment, IP = offset )로 점프합니다.

명령은 코드 크기에 따라 EA <imm32/48> 로 인코딩됩니다.
예를 들어, NASM jmp 7c0h: WORD 0000hjmp 7c0h: DWORD 0000h 와 같은 일부 어셈블러에서 두 가지 형식 중에서 선택할 수 있습니다 jmp 7c0h: DWORD 0000h 는 첫 번째 및 두 번째 형식을 생성합니다.

절대 간접 멀리뛰기

jmp FAR WORD [aFarPointer] 는 다음과 같습니다.

  • far 논리 주소의 두 부분 인 세그먼트와 오프셋을 지정합니다.

  • Absolute indirect 명령의 의미는 mem 2 또는 CS = mem[23:16/32], IP = [15/31:0] 저장된 세그먼트 : 점프로 점프합니다.

명령은 FF /5 로 인코딩되며 피연산자의 크기는 크기 지정자가있는 컨트롤러가 될 수 있습니다.
NASM에서 조금 비 직관적 그것들은 jmp FAR WORD [aFarPointer] 16시 16분 피연산자 및 jmp FAR DWORD [aFarPointer] 16시 32분 피연산자.


누락 된 점프

  • 절대 근처
    가까운 간접 점프로 에뮬레이션 가능.

      mov bx, target            ;BX = absolute address of target
      jmp bx
    
  • 먼 친척
    어쨌든 사용의 의미 또는 너무 좁은합니다.


1 부호가있는 오프셋을 지정하기 위해 두 개의 보수가 사용되므로 역방향으로 점프합니다.
크기 16시 16분16시 32분의 off32 : off16 또는 seg16하십시오 seg16 할 수있다 2.

시험 조건

조건부 점프를 사용하려면 조건을 테스트해야합니다. 여기 에서 조건을 테스트하는 것은 플래그를 확인하는 행위에만 해당되며 실제 점프는 조건부 점프에서 설명됩니다.

x86은 각 명령어가 잠재적으로 설정할 수있는 플래그 세트를 보유하고있는 EFLAGS 레지스터에 의존하여 조건을 테스트합니다.

sub 또는 add 와 같은 산술 명령어와 xor and or and 같은 논리 명령어는 분명히 플래그를 설정합니다. 이는 CF , OF , SF , ZF , AF , PF 플래그가 해당 지침에 의해 수정됨을 의미합니다. 모든 명령어는 플래그를 수정할 수 있습니다. 예를 들어 cmpxchgZF를 수정합니다.

특정 명령어에 의해 수정 된 플래그를 확인하려면 항상 명령어 참조확인하십시오 .

x86은 앞에서 언급 한 일련의 조건부 점프를 가지고 있는데, 이는 일부 플래그가 설정되거나 일부가 해제되거나 모두 인 경우에만 점프합니다.


국기

산술 및 논리 연산은 플래그를 설정할 때 매우 유용합니다. 예를 들어, sub eax, ebx )가 서명되지 않은 값을 갖고있는 경우,

깃발 설정시 취소 할 때
ZF 결과가 0 일 때
EAX - EBX = 0 ⇒ EAX = EBX
결과가 0이 아닌 경우
EAX - EBX ≠ 0 ⇒ EAX ≠ EBX
CF 결과가 MSb에 대해 수행해야하는 경우.
EAX - EBX <0 ⇒ EAX <EBX
결과가 MSb를 위해 나올 필요가 없는 경우.
EAX - EBX ≮ 0 ⇒ EAX ≮ EBX
SF 결과 MSb가 설정된 경우. 결과 MSb가 설정 되지 않은 경우 .
서명 된 오버플로가 발생했습니다. 서명 된 오버 플로우가 발생하지 않은 경우 .
PF 결과의 최하위 바이트에 설정된 비트 수가 짝수 일 때. 결과의 최하위 바이트에 설정된 비트 수가 홀수 일 때.
AF 낮은 BCD 숫자가 캐리를 생성 할 때.
비트 4 캐리입니다.
낮은 BCD 숫자가 캐리를 생성하지 않은 경우.
비트 4 캐리입니다.

비파괴 검사

suband 명령은 대상 피연산자를 수정하며 대상을 수정하지 않고 유지하기 위해 두 개의 추가 복사본 (저장 및 복원)이 필요합니다.

비파괴 검사를 수행하려면 cmptest 지침이 있습니다. 연산의 결과가 무시되고 플래그 만 저장된다는 점을 제외하고는 상 대방과 동일합니다 .

파괴적인 비 파괴적인
sub cmp
and test

test eax, eax             ;and eax, eax
                          ;ZF = 1 iff EAX is zero

test eax, 03h             ;and eax, 03h
                          ;ZF = 1 if both bit[1:0] are clear
                          ;ZF = 0 if at least one of bit[1:0] is set

cmp eax, 241d             ;sub eax, 241d
                          ;ZF = 1 iff EAX is 241
                          ;CF = 1 iff EAX < 241

서명 된 테스트와 서명되지 않은 테스트

CPU는 값 1 을 등록하는 특별한 의미가 없으며, sign은 프로그래머 구성입니다. 부호있는 값과 부호없는 값을 테스트 할 때 차이점은 없습니다. 프로세서는 피연산자가 부호가 있거나 부호가없는 것으로 간주되어야하는 경우 일반 산술 관계 (같음,보다 작음,보다 큼 등)를 테스트하기에 충분한 플래그를 계산합니다.


1 2의 보수와 같은 특정 형식에서만 의미가있는 지침이 있지만. 이것은 소프트웨어에서 알고리즘을 구현할 때 많은 코드가 필요하므로 코드를보다 효율적으로 만드는 것입니다.

조건부 점프

플래그의 상태에 따라 CPU는 점프를 실행하거나 무시할 수 있습니다. 플래그를 기반으로 점프를 수행하는 명령어는 Jcc - Jump on Condition Code 1 이라는 일반 이름 아래에 있습니다.

동의어 및 용어

어셈블리 코드의 가독성을 향상시키기 위해 인텔은 동일한 조건 코드에 대해 몇 가지 동의어를 정의했습니다. 예를 들어, jae , jnbjnc 는 모두 동일한 조건 코드 CF = 0 입니다.

명령어 이름은 언제 사용할지에 대한 매우 강력한 힌트를 줄 수 있지만, 유일한 의미있는 접근법은 테스트해야하는 플래그를 인식 한 다음 지침을 적절히 선택하는 것입니다.
인텔은 cmp 명령 후에 사용할 때 완벽하게 이해할 수있는 지침 이름을 제공했습니다. 이 토론의 목적을 위해, cmp 는 조건부 점프 전에 플래그를 설정했다고 가정합니다.

평등

ZF 가 설정되면 피연산자는 동일합니다. 그렇지 않으면 피연산자가 다릅니다. 평등을 테스트하려면 ZF = 1이 필요합니다.

je a_label           ;Jump if operands are equal
jz a_label           ;Jump if zero (Synonym)

jne a_label          ;Jump if operands are NOT equal
jnz a_label          ;Jump if not zero (Synonym)
교수 국기
je , jz ZF = 1
jne , jnz ZF = 0

보다 큰

부호없는 피연산자의 경우 carry가 필요하지 않은 경우, 즉 CF = 0 인 경우 대상이 소스보다 큽니다. CF = 0 일 때 피연산자가 같을 수 있으므로 테스트 ZF 가 모호해집니다.

jae a_label      ;Jump if above or equal (>=)
jnc a_label      ;Jump if not carry (Synonym)
jnb a_label      ;Jump if not below (Synonym)

ja a_label       ;Jump if above  (>)
jnbe a_label     ;Jump if not below and not equal (Synonym)
교수 국기
jae , jnc , jnb CF = 0
ja , jnbe CF = 0, ZF = 0

부호가있는 피연산자의 경우 서명 된 오버 플로우가없는 한 SF = 0 인지 확인해야합니다.이 경우 SF 가 반전됩니다. 부호있는 오버 플로우가 발생하지 않으면 OF = 0 이고, 그렇지 않으면 1이므로 SF = OF 인지 확인해야합니다.

엄격한 / 엄격하지 않은 테스트를 구현하는 데 ZF를 사용할 수 있습니다.

jge a_label      ;Jump if greater or equal (>=)
jnl a_label      ;Jump if not less (Synonym)

jg a_label       ;Jump if greater (>)
jnle a_label     ;Jump if not less and not equal (Synonym)
교수 국기
jge , jnl SF = OF
jg , jnle SF = OF, ZF = 0

미만

위의 거꾸로 된 조건을 사용합니다.

jbe a_label      ;Jump if below or equal (<=)
jna a_label      ;Jump if not above (Synonym)

jb a_label       ;Jump if below (<)
jc a_label       ;Jump if carry (Synonym)
jnae a_label     ;Jump if not above and not equal (Synonym)

;SIGNED 

jle a_label      ;Jump if less or equal (<=)
jng a_label      ;Jump if not greater (Synonym)

jl a_label       ;Jump if less (<)
jnge a_label     ;Jump if not greater and not equal (Synonym)
교수 국기
jbe , jna CF = 1 또는 ZF = 1
jb , jc , jnae CF = 1
jle , jng SF! = OF 또는 ZF = 1
jl , jnge SF! = OF

특정 플래그

각 플래그는 j<flag_name> 하여 개별적으로 테스트 할 수 있습니다. 여기서 flag_name 에는 후행 F (예 : CFC , PFP )가 없습니다.

이전에 다루지 않은 나머지 코드는 다음과 같습니다.

교수 깃발
js SF = 1
jns SF = 0
jo OF = 1
jno OF = 0
jp , jpe (e = 짝수) PF = 1
jnp , jpo (o = 홀수) PF = 0

하나 더 조건부 점프 (여분의 것)

하나의 특별한 x86 조건부 점프는 플래그를 테스트하지 않습니다. 대신 cx 또는 ecx 레지스터의 테스트 값 (현재 CPU 주소 모드가 16 또는 32 비트 임)을 기반으로하며 레지스터에 0이 있으면 점프가 실행됩니다.

이 명령어는 rep 와 유사한 명령보다 먼저 카운터 레지스터 ( cx/ecx )의 유효성을 검사하거나 loop 루프보다 먼저 검증하도록 설계되었습니다.

jcxz  a_label   ; jump if cx (16b mode) or ecx (32b mode) is zero
jecxz a_label   ; synonym of jcxz (recommended in source code for 32b target)
교수 등록 (플래그가 아님)
jcxz , jecxz cx = 0 (16b 모드)
jcxz , jecxz ecx = 0 (32b 모드)

1 또는 그런 것.

산술 관계 테스트

부호없는 정수

보다 큰

cmp eax, ebx
ja a_label  

크거나 같음

cmp eax, ebx
jae a_label  

미만

cmp eax, ebx
jb a_label  

작거나 같음

cmp eax, ebx
jbe a_label 

같은

cmp eax, ebx
je a_label 

같지 않음

cmp eax, ebx
jne a_label     

부호있는 정수

보다 큰

cmp eax, ebx
jg a_label  

크거나 같음

cmp eax, ebx
jge a_label  

미만

cmp eax, ebx
jl a_label  

작거나 같음

cmp eax, ebx
jle a_label 

같은

cmp eax, ebx
je a_label 

같지 않음

cmp eax, ebx
jne a_label 

a_label

위의 예제에서 a_label 은 테스트 된 조건이 "true"인 경우 CPU의 대상 대상입니다. 테스트 된 조건이 "거짓"인 경우 CPU는 조건부 점프 다음의 명령을 계속 수행합니다.

동의어

코드의 가독성을 높이기 위해 사용할 수있는 명령어 동의어가 있습니다.
예를 들어 jajnbe (점프가 아닌 점 이하) 점은 같은 명령입니다.

서명 된 컴패니언 코드에 서명 됨

조작 서명되지 않은 서명 됨
> ja jg
> = jae jge
< jb jl
<= jbe jle
= je je
≠,! =, <> jne jne


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow