数据字之间。此外MASM装配8086进位标志 [英] Masm assembly 8086 carry flag between data word addition

查看:298
本文介绍了数据字之间。此外MASM装配8086进位标志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有这个问题,我认为要解决,我已经花了几个小时试图找出做到这一点的最好方式,谷歌一直没有太大的帮助。

问题是创建一个给出的话,你然后与成为输出的另一个列表中添加的列表的子程序。它基本上是与大量的工作方法。

我的code工作正常,在字进位标志,但对于进位从一个完整的字到另一个它不工作。第一个16位字(0005下面的例子)是用来告诉我子程序多少字有一个标志。

有关例如,给定下列输入,

  // SI 0005 0000 EEEE DDDD BBBB CCCC
//迪0005 0000 1111 2222 3333 4445

在预期输出是:

  0005 0001 0000 0000 0000 0000

我的code生产:

  0005 0000 FFFF FFFF FFFF 0000

我相信我明白这是为什么发生的大部分,但我不确定来解决这个问题的最佳途径。我需要携带超过​​1不同的数据块之间的一个低成本的方法。

 ; ------------------------------- - 
; ADD子程序
; ---------------------------------------
    。数据    BXX DW 0000H;
    CXX DW 0000H;    。code
; ---------------------------------------
ADDX:;
    MOV BXX,BX;保存输入寄存器
    MOV CXX,CX;保存输入寄存器
    MOV BX,SI;移动n至BL - 作为一个游标
loopAdd:;循环点
    MOV CX,[SI + BX];在点SI + BX招字到寄存器CX
    ADC [DI + BX] CX;加上随身带
    子BX,0002H; ;递减光标通过一个完整的字
    CMP BX,0000H; BX == 0?
    JG loopAdd;没有?跳转到循环点
结束: ;
    MOV BX,BXX;返回注册到原来的状态
    MOV CX,CXX;返回注册到原来的状态
    RET;返回
; ---------------------------------------


解决方案

您必须从previous迭代保存进位标志。

试试这个:

 ; ------------------------------- - 
; ADD子程序
; ---------------------------------------
    。数据    BXX DW 0000H;
    CXX DW 0000H;    。code
; ---------------------------------------
ADDX:;
    MOV BXX,BX;保存输入寄存器
    MOV CXX,CX;保存输入寄存器
    MOV BX,SI;移动n至BL - 作为一个游标
    CLC;清除进位标​​志
    PUSHF;保存标志寄存器
loopAdd:;循环点
    MOV CX,[SI + BX];在点SI + BX招字到寄存器CX
    POPF;恢复保存标志寄存器
    ADC [DI + BX] CX;加上随身带
    PUSHF;保存标志寄存器
    子BX,0002H; ;递减光标通过一个完整的字
    JG loopAdd;如果结果是肯定的,跳转到循环点
结束: ;
    POPF;从堆栈中删除保存的标志寄存器
    MOV BX,BXX;返回注册到原来的状态
    MOV CX,CXX;返回注册到原来的状态
    RET;返回
; ---------------------------------------

注意 CMP BX,0000H 没有必要的,因为 CMP 除了 CMP 只修改标志,不存储计算的值,这样你就可以检查直接

So I have this problem I'm supposed to solve and I've spent hours trying to figure out the best way to do this, google hasn't been of much help.

The problem is to create a subroutine that is given a list of words that you then add with another list that becomes the output. Its basically a method of working with large numbers.

My code works fine for carry flags within words, but for carry flag from one full word to another it does not work. The first 16 bit word (0005 in the example below) is a flag used to tell my subroutine how many words there are.

For instance, given the following input,

//si     0005 0000 EEEE DDDD CCCC BBBB
//di     0005 0000 1111 2222 3333 4445

when the output expected is:

0005 0001 0000 0000 0000 0000

My code produces:

0005 0000 FFFF FFFF FFFF 0000 

I believe I understand why this is happening for the most part, but am unsure of the best way to solve this issue. I need a low cost method of carrying over a 1 between different chunks of data.

;---------------------------------------
; ADD Subroutine
;---------------------------------------
    .data

    bxx dw 0000h                        ;
    cxx dw 0000h                        ;

    .code
;---------------------------------------
addx:                                   ;
    mov bxx, bx                         ;save incoming register
    mov cxx, cx                         ;save incoming register
    mov bx, si                          ;move n to bl - acts as a cursor
loopAdd:                                ;loop point
    mov cx, [si+bx]                     ;move word at point si+bx into register cx
    ADC [di+bx], cx                     ;add with carry  
    sub bx, 0002h;                      ;decrement cursor by a full word
    cmp bx, 0000h                       ;bx == 0?
    jg loopAdd                          ;no? jump to loop point
end:                                    ;
    mov bx, bxx                         ;return register to original state
    mov cx, cxx                         ;return register to original state
    ret                                 ;return
;---------------------------------------

解决方案

You have to save the carry flag from the previous iteration.

Try this:

;---------------------------------------
; ADD Subroutine
;---------------------------------------
    .data

    bxx dw 0000h                        ;
    cxx dw 0000h                        ;

    .code
;---------------------------------------
addx:                                   ;
    mov bxx, bx                         ;save incoming register
    mov cxx, cx                         ;save incoming register
    mov bx, si                          ;move n to bl - acts as a cursor
    clc                                 ;clear carry flag
    pushf                               ;save flag register
loopAdd:                                ;loop point
    mov cx, [si+bx]                     ;move word at point si+bx into register cx
    popf                                ;restore saved flag register
    ADC [di+bx], cx                     ;add with carry
    pushf                               ;save flag register
    sub bx, 0002h;                      ;decrement cursor by a full word
    jg loopAdd                          ;if the result is positive, jump to loop point
end:                                    ;
    popf                                ;remove saved flag register from the stack
    mov bx, bxx                         ;return register to original state
    mov cx, cxx                         ;return register to original state
    ret                                 ;return
;---------------------------------------

Note that cmp bx, 0000h isn't needed because cmp is sub except for cmp only modify flags and don't store calculated value, so you can check the result of sub directly.

这篇关于数据字之间。此外MASM装配8086进位标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆