2017-11-13 4 views
-2

코드를 많이 줄여야하는데 Assembly x16의 한 줄에 몇 가지 명령을 쓸 수 있는지 여부를 생각했습니다. 예를 들어어셈블리 : 한 줄에 명령이 거의 없습니다.

MOV cl,10b CMP cl,10b JE label 

위와 같이 작성하는 것은 불가능하지만 이러한 명령을 결합 할 수있는 방법이 있습니다. 감사!

이것은 내가 디스어셈블러에서 사용한 절차 중 하나입니다. 나는 모든 명령을 식별 할 필요가 없다는 것을 알려 드리고자합니다! 내가 알아야 할 모든 명령 변형을 작성했습니다. 이것은 네 가지 절차 중 하나이며, 명령을 식별합니다. 이 방법을 사용하여이 작업을 수행했습니다. 먼저 작업 코드의 처음 두 비트를 취해 네 개의 그룹 (00,01,10,11)으로 나누고 각 그룹에서 비트와 함께 계속 수행합니다.

THIS IS THE PROCEDURE THAT HELPS TO FIND THE OPERATION CODE 
PROC FINDOPK 
     opk11:      ;first two bits of operation coda are 11 
       MOV al,opk 
       AND al,00110000b 
       SHR al,4 
       CMP al,01b 
       JE opk1101 
       CMP al,10b 
       JE opk1110 
       CMP al,11b 
       JE opk1111 ;opk1100 starts here 
        MOV al,opk 
        AND al,00001100b 
        SHR al,2 
        CMP al,01b 
        JE opk110001 
        CMP al,10b 
        JE opk110010 
        CMP al,11b 
        JE opk110011 ;opk110000 starts here 
         MOV al,opk 
         AND al,00000011b 
         CMP al,10b 
         JE opk11000010 
         CMP al,11b 
         JE opk11000011 ;opk11000000 ir opk11000001 
          JMP neatpazinta ;it means that i didn't have to identify this command and it prints that 
         opk11000010: ;Doing stuff if operation code is like this 
          ; 
         opk11000011: ;Same here 
          ;  
        opk110001: 
         MOV al,opk 
         AND al,00000011b 
         CMP al,10b 
         JE opk11000110 
         CMP al,11b 
         JE opk11000111 ;opk11000100 ir opk11000101 
          JMP neatpazinta 
         opk11000110: 
          ; 
         opk11000111: 
          ;   
        opk110010: 
         MOV al,opk 
         AND al,00000011b 
         CMP al,11b 
         JE opk11001011 ;opk11001000 ir opk11001001 ir opk11001010 
          JMP neatpazinta  
         opk11001011: 
          ;   
        opk110011: 
         MOV al,opk 
         AND al,00000011b 
         CMP al,01b 
         JE opk11001101 
         CMP al,11b 
         JE opk11001111 ;opk11001100 ir opk11001110 
          JMP neatpazinta 
         opk11001101: 
          ; 
         opk11001111: 
          ;   
       opk1101: 
        JMP neatpazinta 
       opk1110: 
        MOV al,opk 
        AND al,00001100b 
        SHR al,2 
        CMP al,00b 
        JE opk111000 
        CMP al,10b 
        JE opk111010 ;opk111001 ir opk 111011 
         JMP neatpazinta 
        opk111000: 
         MOV al,opk 
         AND al,00000011b 
         CMP al,10b 
         JE opk11100010 
         CMP al,11b 
         JE opk11100011 ;opk11100000 ir opk11100001 
          JMP neatpazinta 
         opk11100010: 
          ; 
         opk11100011: 
          ; 
        opk111010: 
         MOV al,opk 
         AND al,00000011b 
         CMP al,01b 
         JE opk11101001 
         CMP al,10b 
         JE opk11101010 
         CMP al,11b 
         JE opk11101011 ;opk11101000 
          ; 
         opk11101001: 
          ; 
         opk11101010: 
          ; 
         opk11101011: 
          ;   
       opk1111: 
        MOV al,opk 
        AND al,00001100b 
        SHR al,2 
        CMP al,01b 
        JE opk111101 
        CMP al,11b 
        JE opk111111 ;opk111100 ir opk 111110 
         JMP neatpazinta 
        opk111101: 
         MOV al,opk 
         AND al,00000011b 
         CMP al,10b 
         JE opk11110110 
         CMP al,11b 
         JE opk11110111 ;opk11110100 ir opk11110101 
          JMP neatpazinta 
         opk11110110: 
          ; 
         opk11110111: 
          ; 
        opk111111: 
         MOV al,opk 
         AND al,00000011b 
         CMP al,10b 
         JE opk11111110 
         CMP al,11b 
         JE opk11111111 ;opk11111100 ir opk11111101 
          JMP neatpazinta 
         opk11111110: 
          ; 
         opk11111111: 
          ; 
      neatpazinta: 
       CALL SpausdinkNeatpazinta   
      SkipOPK: 
     RET 
     FINDOPK ENDP 
+3

제발, 제발. 이와 같은 어셈블리 코드를 작성하지 마십시오. 이렇게하면 아무 것도 속도를 높이 지 못하고 코드가 엉망이되어 어셈블 할지라도 읽을 수 있습니다. 대신에, 각각의 개별 라인에 무슨 일이 일어나고 있는지 설명하여, 상위 레벨의 프로그래머가 "이상한 외계인 컴퓨터 스크립트"로 보는 것을 파싱하지 않고 읽을 수 있도록하는 것을 고려해보십시오. –

+0

무엇이 요점입니까? 소스 코드 또는 기계어 코드를 단축 하시겠습니까?한 줄에 3 개의 명령어를 작성하는 것이 가능하다면, 여전히 같은 양의 기계어 코드로 컴파일되므로 실행 파일의 크기는 동일합니다. 소스를 줄이는 것이 정말로 필요하다면, 머신 코드 자체 대신에'db 0xB1, 0x02, 0x80, 0xF9, 0x02, 0x74, 0xF9' 대신에 쓸 수있다. (마지막'F9'는 점프를위한 상대 주소이다. 레이블을 이동할 때마다 매번 다시 계산하고 수정해야합니다). ...하지만 이것은 의미가 없습니다. – Ped7g

+1

어셈블리 코드의 최단 형태는 당연히 원시 바이너리입니다 ... (또한 최단 코드는 존재하지 않는 코드입니다 (버그가 적습니다!). 예를 들어 여러분이 작성한 라인은'jmp label'입니다. 기능적으로 3 가지 지시가 필요 없음). – Ped7g

답변

1

일부 조립품 구문을 사용하면 한 줄에 여러 명령어를 작성할 수 있습니다. 예를 들어, GAS (GNU 어셈블러)는 ;을 구분 기호로 사용합니다. (#은 주석 문자입니다).

.intel_syntax noprefix 
MOV cl,10b; CMP cl,10b; JE label 

NASM 구문은 일반적으로 유용하지 않기 때문에 이것을 허용하지 않습니다.

내가 많은 어셈블리

내 코드를 단축 할 수 있고, 일반적으로이 당신이 기계 코드 아닌 크기 또는 라인 카운트의 코드 크기에 대한 걱정 의미 텍스트 소스.

이것은 코드를 최적화하여 더 적은 수의 명령어 나 더 짧은 명령어가 필요하다는 것을 의미합니다. 아이디어를 얻으려면 Adler32 in 31 bytes of x86-32 machine code처럼 codegolf.SE에 대한 내 x86 컴퓨터 코드 응답 일부를 참조하십시오. (물론 NASM 소스는 기계 코드와 함께 포함되어 있습니다.) 귀하의 경우에는

je는 항상 cl이 필요하고 당신이 label에 도달하면 플래그 설정 내용에 따라, 단지 jmp label을 당신은 아마 그 대부분을 최적화 할 수 있도록 촬영하고있다. 당신은 정확히 같은 건축 상태를 얻을 수이에서 (ECX = 10b의 하위 바이트를, ZF 세트, CF는,의, SF 클리어) :

MOV cl,10b 
CMP cl,cl 
JE label 

흥미롭게도, je label 현대 CPU에서 jmp label보다 더 효율적일 수 있습니다 왜냐하면 매크로가 cmp과 함께 하나의 uop에 통합 될 수 있기 때문입니다. label이 설정중인 플래그에 의존하지 않으면이 작업을 수행 할 수 있습니다.

MOV cl,10b 
JMP label 

하지만 실제로는 뒤로 물러나서 더 큰 규모로 최적화를 찾아야합니다. label에 빠질 수 있도록 지점을 배치하십시오.

+0

내 코드에서 2200 줄에서 1500 줄로 줄여야합니다./ – Deividito

+0

@Deividito : 왜 줄 수가 정확히 무엇과 관련이 있습니까? 1.5k 제한을 정확히 부과하는 것은 무엇입니까? 그리고 어떤 어셈블러를 사용하고 있습니까? (NASM? MASM?'gas'로 전환하고 전체 프로그램을 한 줄에 넣을 수 있습니까? 기계 코드의 크기는 전혀 변하지 않을 것입니다.) –

+1

@Peter Cordes : 운동에 부과 된 인위적인 한도가되어야한다. 개인적으로 나는 매크로를 깰 것이다. 샘플 코드에는 추출 할 패턴이 많으며 사려 깊게 사용하면 내용을 정리할 수도 있습니다. – doynax