0

I have the following code:

#make_COM#          

org 100h
    A DD 13d          
    x DD 0d          
    y DD 1d          
    z DD 0d          
    mov dx,A          
    dec dx           
    
    xor cx,cx        

while_begin:          
    
    cmp cx,dx        
    jge while_end    
    
    mov ax,x
    mov bx,y                         
    add ax,y
    daa                                                           
    mov z,ax
    mov x, bx
    mov bx,z                        
    mov y, bx
    inc cx           
    jmp while_begin  

while_end:           
    
    mov ax,x          
    
    int 20h            

This code should retrieve a number from the Fibonacci sequence with a given index in the A variable. But this code only works as long as variable A is less than or equal to 12

UPD: This is my current code, now it works for values of A greater than 12:

#make_COM#             

org 100h

    
    A DW 16
    x DW 0d         
    y DW 1d          
    z DW 0d          
    mov dx,[A]
    sub dx,2              
    
    xor cx,cx         

while_begin:          
    
    cmp cx,dx        
    jge while_end    
    
    mov ax,[x]
    add ax,[y]
    mov [z],ax
    mov ax,[y]
    mov [x],ax
    mov ax,[z]
    mov [y],ax
     
    
    inc cx           
    jmp while_begin  

while_end:           
    mov ax,[x]
    add ax,[y]
    daa
    mov [z],ax
    mov ax,[y]
    mov [x],ax
    mov ax,[z]
    mov [y],ax  
        
   
    int 20h     

The problem was how I used the A variable and how I used its value. Proof of work

  • This is a little confusing. `DD` defines double words (32-bit values), you are only operating on 16-bit values, and `daa` is for 2-digit (8-bit) BCD. For BCD, you exceed two decimal digits in Fibonacci at `A` value of 13 (The 13th Fibonacci value is 144, whereas the 12th is 89). So at `A` of 13, you overflow the byte that holds a 2 digit BCD value. – lurker Dec 23 '21 at 16:33
  • @lurker I apologize for not expressing myself correctly. I use Emu8086. I get the wrong result when the value is higher than 12 in the A variable. In this state, with the value of the variable A is 12, the program gives the answer as 89 (in decimal notation), which corresponds to reality. At values above 12 I get incomprehensible values in the CX register. [Image](https://imgur.com/a/3etkVlC) – Anton Shabanov Dec 23 '21 at 16:36
  • @lurker Thanks for the explanation of daa's work. I think that was the point. UPD: That wasn't the point. – Anton Shabanov Dec 23 '21 at 16:38
  • I believe that actually *is* the point. As I said, due to the BCD operation limit, it fails when `A` is higher than 12. I would examine the operation of your code when the Fibonacci number reaches 144. – lurker Dec 23 '21 at 16:43
  • According to the documentation for `daa`, the carry flag is set on a decimal carry. So you could modify your code to handle two-byte BCD values and that should fix the problem for up to 4 digits limit. – lurker Dec 23 '21 at 17:22
  • This may help: [Packed BCD 4-digit addition 8086 assembler](https://stackoverflow.com/questions/28250388/packed-bcd-4-digit-addition-8086-assembler). This answer given by "herold" is what you'd want. – lurker Dec 23 '21 at 17:48
  • I found the problem, it had nothing to do with the limitations of the BCD. It worked right after I removed the A variable and just passed the index directly to the DX register. Thank you for your help @lurker – Anton Shabanov Dec 23 '21 at 19:36
  • And I was able to return the variable A – Anton Shabanov Dec 23 '21 at 19:51
  • I kind of thought `mov dx, A` looked fishy, but I didn't know what assembler you were using (it wasn't mentioned). Certainly for assemblers like `masm` the `mov dx, A` would move the address of `A` to `dx` and you'd need `[A]` to get what the symbol `A` refers to in memory. I'm still a little surprised the BCD works because `daa` only works on a 2-digit BCD value, but your values are up to 4 digits. But does it really work? Your program shows 833 for Fib 16, but it should be 987. – lurker Dec 23 '21 at 20:16
  • @lurker: You're thinking of NASM where `mov dx,A` is `mov dx, imm16` with the address. In MASM, `mov dx, A` is the same thing as `mov dx, [A]`, at least for "variables" defined in .data sections, and probably for labels in the default .text section like here. This would assemble with NASM, but might also assemble with MASM, IDK, so I can't tell either which syntax it is. For a load, it's better to make it unambiguous with `mov dx, [A]`. Looks like the real problem here is putting data in the path of execution (at the top of a .com file) without even jumping over it. – Peter Cordes Dec 24 '21 at 01:40
  • @lurker: Oh nvm, this is tagged emu8086, which has its own assembler which uses MASM-like syntax. Anyway, [Assembly (x86): db 'string',0 does not get executed unless there's a jump instruction](https://stackoverflow.com/q/30561366) applies. Anton: use a disassembler to see how `12` decodes vs. `11` or other values that work. – Peter Cordes Dec 24 '21 at 01:42

0 Answers0