2016-11-27 6 views
1

어셈블리 언어로 모델링 할 방정식이 있습니다. 구문 상 올바르지 만 레지스터에 잘못된 결과를 생성하는 다음 코드를 작성했습니다. 최종 결과는 DX 레지스터에 저장됩니다. I는 모델링하고 방정식은 다음어셈블리 언어 (Intel)에서 수학 방정식이 잘못 계산 됨

DX = (AX2 + (AX -1) + 2 * (AX +2))/2

다음은 인텔 마이크로 프로세서의 어셈블리 언어 코드입니다.

[org 0x0100] 
      jmp start 

number:   db 02 
multiplicand: db 0 
multiplier:  db 0 
multiResult: dw 0 
squareResult: dd 0 


square:  mov [multiplicand], AX 
      mov [multiplier], AX 
      call multi 
      mov AX, [multiResult] 
      mov [squareResult], AX 
      ret 


multi:   mov CL, 8 
       mov BX, [multiplicand] 
       mov DX, [multiplier] 

carryCheck:  shr BX, 1 
       jnc skip 

       add [multiResult], BX 


skip:   shl BX, 1 
       dec CL 
       jnz carryCheck 
       ret 


start:   mov AX, [number] 
       call square 
       mov DX, [squareResult] 
       sub byte[number], 1 
       add DX, AX 
       add byte[number], 2 
       mov AX, [number] 
       mov [multiplicand],AX 
       mov byte[multiplier], 2 
       call multi 
       add DX, [multiResult] 
       shr DX, 1     ; division by 2 

      mov AX, 0x4c00    ;ending program 
      int 0x21 
+2

디버거를 사용하여 코드를 단계별 실행하면 오류가 발생한 곳을 확인할 수 없습니까? –

+1

당신은 단지'db' 바이트 저장을 가지고 있지만'AX'와 다른 16 비트 레지스터를 읽고 쓰는 것 : collision. 'db' ==>'dw'. –

+1

왜 어셈블리 코드에서 주석을 사용하지 않습니까? –

답변

1

당신은 이것을 방법으로 만들려고합니다. 너무 복잡합니다.

mov dx, ax 
add dx, 3  ; dx = ax+3 

mul dx   ; dx:ax = ax * (ax+3) 

inc ax   ; ignore the high-half of the mul result in DX. 
shr ax, 1 

mov dx, ax  ; apparently you want the result in DX? 

또는 32 비트 임시직을 유지하기로되어있다 : 첫째, 구현하기 쉽고 간단합니다

(AX*AX + (AX-1) + 2 * (AX+2))/2; 
(AX*AX + AX + 2*AX - 1 + 2)/2 
(AX*AX + 3*AX + 1)/2 
(AX*(AX+3) + 1)/2 

을 계산하기 쉽게 하나에 식을 단순화? 그렇다면 ADD/ADC를 사용하여 DX : AX에 1을 더하십시오. emu8086 등을 사용하는 경우 SHRD를 사용하여 DX에서 AX로 비트를 이동할 수 없습니다. 따라서 SHR을 사용하여 DX에서 조금 벗어나고 RCR로 비트를 AX로 옮길 수 있습니다.

이렇게하면 AX + 3의 캐리 아웃을 저장해야합니다.


자세히, 컴파일러에게 아이디어를 요청할 수 있습니다. gcc는 실제로 순수한 16 비트를 수행하지는 않지만, 32 비트 모드로 컴파일하는 32 비트 unsigned을 사용하면 16 비트 어드레싱 모드가 지원하지 않는 방식으로 LEA를 사용합니다. 하지만 여기에 what I tried on Godbolt이 있습니다.


원래 코드를 수정하려면 디버거를 사용하십시오. 왜 당신이 무엇인가에 대해 분지를 세우고 있거나 어떤 것을 위해 메모리를 사용하고있는 IDK는 아무런 코멘트가 없습니다.

0

shr BX, 1은 라벨의 경우 shr DX, 1이어야합니다.

+0

날씨 베인 (Weather Vane)의 의견에서 언급했듯이 단어 값이 바이트 간격 레이블이있는 주소에 쓰여지는 경우 가변적 인 맹 글링 가능성이 있습니다. (쓰여진 것처럼) 코드는 올바른 값을 주소에 쓰지만 'square :'레이블에있는 두 개의 'mov'명령의 순서가 바뀌면 그 결과는 틀릴 것입니다. –