2011-12-07 3 views
3

인텔 설명서를 읽는 것이 이해되면 "add $ 0x7f, % ebx"와 같은 명령어를 작성할 수 있어야하며 총 3 바이트로 83/0 ib로 인코딩되어야합니다. 그러나 "add", "addb"또는 "addl"을 사용하더라도이 작업을 수행하면 즉시 값을 32 비트 값으로 "승격"하고 81/0 id로 인코딩하고 6 바이트를 차지합니다. adc, sub 등과 같은 문제가 있습니다. & GNU와 T 문법을 사용하고 있습니다.x86에서 AT & T 구문을 사용하여 긴 레지스터에 즉시 바이트를 추가하는 방법은 무엇입니까?

나는 하루 동안 해결책을 찾고 있었지만 그것을 찾지 못했습니다. 아무도 조언을 해줄 수 있습니까?

답변

2

놀랍게도, 나는 그런 문제가 없습니다.

나는 gcc (DJGPP)에 의해 생산이 어셈블리 코드에 나섭니다 :

 .file "im.c" 
.globl _x 
     .section  .bss 
     .p2align 2 
_x: 
     .space 4 
     .section .text 
     .p2align 4,,15 
.globl _main 
_main: 
     pushl %ebp 
     movl %esp, %ebp 
     pushl %eax 
     pushl %eax 
     movl _x, %eax 
     andl $-16, %esp 
     addl $127, %eax 
     movl %eax, _x 
     movl %ebp, %esp 
     xorl %eax, %eax 
     popl %ebp 
     ret 
     .ident "GCC: (GNU) 3.3.4" 

를 그리고 컴파일을 as으로이 내가 a.out의에서보고 있어요 무엇 :

55    push ebp 
89E5    mov ebp,esp 
50    push eax 
50    push eax 
A100000000  mov eax,[0x0] 
83E4F0   and esp,byte -0x10 
83C07F   add eax,byte +0x7f 
A300000000  mov [0x0],eax 
89EC    mov esp,ebp 
31C0    xor eax,eax 
5D    pop ebp 
C3    ret 

그리고 C 프로그램 :

volatile int x = 0; 

int main(void) 
{ 
    x += 0x7F; 
    return 0; 
} 

귀하의 즉각적인 피연산자는 8 비트 부호있는 정수로 표시됩니까? -128에서 +127 범위를 벗어나면 어셈블러에서 더 긴 인코딩을 사용해야합니다.

+0

매우 이상합니다. eax, ebc, ecx 및 edx에 즉치 값의 256 가지 변형을 모두 방출했으며 각 니모닉 접미어 (b, w 및 l)를 사용했으며 단일 83 인코딩을 얻지 못했습니다. 그들은 모두 81로 나옵니다. 나는 최신의 안정된 우분투를 모으고 있습니다. 앞서 언급 한 다른 지침에도 비슷한 문제가 있습니다. :/ – user1084743

+0

음수 값에 관한 귀하의 의견을 토대로 재시험했습니다. 자신을 0-127 범위의 값으로 제한하면 예상되는 결과를 얻습니다. 고맙습니다. – user1084743

+0

@ user1084743 : 아, 그게 문제입니다. CPU 설명서에 따르면 즉각적인 바이트는 부호로 처리되며 ALU 연산에 사용되기 전에 부호가 확장됩니다. 따라서 비록 +128 또는 +255가 1 바이트 만 필요로하는 것으로 보일지 모르지만, 이는 부호없는 바이트에만 해당됩니다. –