2014-06-11 2 views
1

나는 지난 4 일 동안 힘들어했던이 기계 코드를 가지고있다. 그러나 나는 그것을 잡을 수 없다.C에서이 기계 코드는 어떻게 생겼을까요?

pushl %ebp 
    movl %esp, %ebp 
    jmp .L3 
L4: 
    addl $3,8(%ebp) 

L3: 
    movl 8(%ebp),%eax // having issues here 
    movzbl (%eax),%eax//here 
    cmpb $1,%al// and here 
    je .L5 
    cmpl 12(%ebp),%eax 
    jne .L4 
    movl $8,%eax 
.L5: leave 
    ret 

여기에 솔루션에서 내 시도는 다음과 같습니다

int main(int s, char *t){ 
    while (s != 1) { 
     if (s == *t){ 
      s = 8; 
     } 
     else{s+=3;} 
    } 
    return; 
} 

내가 올바르게 접근하고있어 경우에 누군가가 말해 줄래? 내가 올바른 방향을 가리키는 데 도움이되지 않는다면?

+0

유효한 '주'서명이 아닙니다. 'int main (int argc, char * argv [])'는 일반적인 형식입니다. –

+0

아, 죄송합니다. 기계 코드에 영향을 주는지는 확실하지 않았습니다. – user3395013

+0

@ElliottFrisch : 왜 이것이 '주요한'것이고 다른 어떤 기능이 아니라고 생각합니까? – DCoder

답변

5

기능은 그들이 인수 있음을 나타냅니다하는 중 초기화하지 않고 8(%ebp)12(%ebp) 참조하기 때문에 __cdecl 것으로 보인다. arg1arg2이라고 각각 부릅니다.

우리는 어셈블리 주석을 달 수 있습니다 : C 코드에서

/* Function prologue */ 
    pushl %ebp 
    movl %esp, %ebp 

    jmp .L3 
L4: 
    /* Move to next loop iteration */ 
    addl $3, arg1 

L3: 
    /* Copy value of arg1 to %eax */ 
    movl arg1, %eax 
    /* (%eax) means to dereference %eax (as a memory address). 
     movzbl means to load a single byte and zero-extend to the rest of the register. 
     Therefore, the byte at address %eax is put into %eax. */ 
    movzbl (%eax), %eax 
    /* Compare the low byte of %eax against 1 */ 
    cmpb $1, %al 
    /* If equal, exit (%eax = 1) */ 
    je .L5 
    /* Compare %eax against arg2 */ 
    cmpl arg2, %eax 
    /* If not equal, keep looping */ 
    jne .L4 

    /* Otherwise, if it was equal, we quit and return %eax = 8 */ 
    movl $8,%eax 
.L5: leave 
    ret 

, 이것은

여기
int fn(unsigned char *ptr, int sentinel) { 
    while(1) { 
     unsigned char c = *ptr; 
     if(c == 1) return c; 
     if(c == sentinel) return 8; 
     ptr += 3; 
    } 
} 
+0

아주 철저히 설명해 주셔서 감사합니다. 내가 분해 할 때 movzbl과 cmpb를 볼 수 없을 때 머리카락을 당겨서 사용했습니다! – user3395013

1

이와 비슷한 CDECL 호출 표준을 가정합니다.

int fn(int s, int t){ 
    for(;*(char*)s != 1 && s != t;s += 3); 
    if(s == t) 
     return 8; 
    else 
     return s; 
} 

여기에 설명하지 않은 내용이 있습니다.

movl 8(%ebp),%eax // Load s from stack into register eax. 
movzbl (%eax),%eax // Load a byte from the address in eax (s) and set the higher 3 bytes of eax to 0. 
cmpb $1,%al // Compare that byte loaded to 1. 
+0

유감스럽게 생각 합니다만,'* (char *) s' 부분을 나에게 설명 할 수 있습니까? 나는 아직도이 새로운 것 같습니다. – user3395013

+1

s를 char * (char/byte의 주소)로, * s에서 주소의 바이트를 검색합니다. 형변환 (cast)은 한 유형의 변수가 그 표현의 다른 유형의 변수처럼 취급되어야한다는 것을 컴파일러에게 나타내는 것입니다. 따라서'(char *) 0'은 컴파일러가 int를 0으로 취하고 char의 주소 인 것처럼 처리해야 함을 의미합니다. 전에 NULL을 보았을 수도 있습니다. 단순히'(void *) 0'에 대한 상수입니다. – Tyler

3

은 분해의 주석이 달린 버전이된다 :이에서

pushl %ebp  // save frame pointer 
    movl %esp, %ebp // setup new stack frame 

    // The stack frame looks like this: 
    // 0(%ebp) : previous frame pointer 
    // 4(%ebp) : return address 
    // 8(%ebp) : unsigned char *arg1 
    // 12(%ebp) : int arg2 

    jmp .L3    // jump to loop body 
L4: 
    addl $3,8(%ebp)  // arg1 += 3 

L3: 
    movl 8(%ebp),%eax  // %eax = arg1 
    movzbl (%eax),%eax  // %eax = *arg1 (zero-extend from byte to dword) 
    cmpb $1,%al   // *arg1 == 1? 

    je .L5 

    // *arg1 != 1 
    cmpl 12(%ebp),%eax  // arg2 == *arg1? 

    jne .L4 

    // *arg1 == arg2 
    movl $8,%eax   // result = 8 

.L5: leave 
    ret 

을, 우리 동일한 C 코드를 쓸 수 있습니다 :

int f(unsigned char *p, int v) 
{ 
    unsigned char b; 

    for(; (b = *p) != 1; p += 3) { 
     if(b == v) 
      return 8; 
    } 

    return b; 
} 
관련 문제