2017-05-09 6 views
1

나는 요즘에 & T x86 어셈블리를 배우고 있습니다. "*"를 사용하지 않고 두 개의 32 비트 정수를 곱하는 코드를 작성했습니다. 문제는 디버거가 계속 Segmentation Fault가 발생했다는 것입니다. 여기 내 코드가있다.어셈블리 (GAS)를 사용하기 시작하고이 짧은 코드에 세그먼트 결함이 있습니다.

.global _start 


.data 

a: 
    .long 0 

b: 
    .long 0 

count: 
    .long 0 

.text 

_start: 

    movl $0, %eax 
    movl $a, %ebx 
    movl $b, %ecx 
    movl $0, %edx 

    for_mult: 
     cmpl $32, count 
     je end_for_mult 

     carry_bit: 
      shr $1, %ecx 
      jnc is_zero 

      addl (%ebx), %eax 

      is_zero: 
       shl $1, %ebx 

     incl count 
     jmp for_mult 
    end_for_mult: 

done: 
    movl %eax, %eax 

디버거는 분할 오류가 "ADDL (%의 EBX), % eax에"나타나는지 보여주고, 그 이유를 알아낼 수 없습니다. 도와 줘서 고마워!

+0

당신은'shl $ 1, % ebx'가'ebx'에 어떤 영향을 미치는지, 그리고 이것이 루프의 다음 라운드에서 * addl (% ebx), % eaxx에 어떻게 영향을 주는지를 고려해야합니다. –

+0

디버거가 segmentation fault를 말하고 어떤 명령어를 가르키면, 사용 된 메모리 주소 (이 경우'ebx '의 값)를 확인할 수 있습니다. 그런 다음 할당 된 메모리 (대개'.data' /'.rodata' 섹션 레이블)가 원하는 위치를 가리키는 지 확인할 수 있습니다. 그런 다음 검색을 시작할 수 있습니다 (아마도 코드 1 명령을 단계별로 실행하여). 왜 유효/예상 메모리를 벗어 났는가? Btw, 여전히 몇 가지 무료 레지스터가 있는데, 왜 '카운트'에 하나도 사용하지 않으시겠습니까? 사실 레지스터를 사용하지 않고 왜 메모리에 저장하면됩니까? 일반적으로 더 쉽고 빠릅니다. – Ped7g

답변

2

주소와 값을 혼합합니다.

movl a, %ebx 
movl b, %ecx 

에 $ 표시를 제거은 (코드는 실제로 레지스터에 ab의 주소가 아닌 값을 이동!)

%ebx

addl %ebx, %eax 
주위에 브래킷을 제거

ebx가 가리키는 값이 아닌 값을 원한다.