2016-02-15 33 views
-3

这是我在采访中看到一个问题:执行C = | A-B |与INC,DEC,JNZ(A,B都是非负)

A,B都是非负数和你需要返回C = | AB |在这里你只有以下说明:

  • INC寄存器 - 增加了一个注册
  • DEC寄存器 - 减去一个从寄存器
  • JNZ LABEL - 跳转到标签如果最后一条指令的结果不是零

此外,您可以使用其初始值为零的其他寄存器。

我该如何解决这个问题?

+2

在一个循环就都递减,直到其中一个得到为零。另一个显然是结果。 – Jester

+0

@Jester:如果你在一个循环中递减,你怎么在'jnz'之前测试呢? – EOF

+0

我把这个作为练习留给读者。很明显,在每次循环迭代中,你都需要减少两者,如果第一个循环迭代到零,你需要退出循环并减少其他外部的补偿。你认为这需要一个答案? – Jester

回答

2

只是在一个循环中递减,直到其中一个变为零。另一个显然是结果。

inc a 
    inc b  ; make sure input is not zero 
loop: 
    dec a 
    jnz skip 
    dec b 
    mov eax, b ; return b as answer 
    ret 
skip: 
    dec b 
    jnz loop 
    mov eax, a ; return a as answer 
    ret 
+0

嗯,有趣。而且,想一想,你显然无法避免一些其他的指令('ret'),所以这样做... – EOF

+1

这是否处理A或B中的一个或两个都为零的情况? –

+1

好点,我以某种方式误解了“无负面”为正面,杜。 – Jester

2

只允许可能这个(虽然不是优雅)指令的解决方案。 其中伪寄存器ab保持操作数和伪寄存器c结果(其如前所述最初为零)。

_dec_a: 
dec a 
inc a 
jnz _dec_b 

;a is zero here 

    _a_zero_dec_b: 
    dec b 
    inc b 
    jnz _a_zero_b_non_zero 

;a and b are zero here 

    ;;C is the result 
    inc c 
    jnz _result 

_a_zero_b_non_zero: 
    dec b 
    inc c 
jnz _a_zero_dec_b 

    ;CANNOT FALL HERE 

_dec_b: 
dec b 
inc b 
jnz _subtract 

;b is zero here 

_b_zero_dec_a: 
    dec a 
    inc a 
jnz _b_zero_a_non_zero 

;a and b are zero here 

    ;; C is the result 
    inc c 
    jnz _result 

_b_zero_a_non_zero: 
    dec a 
    inc c 
jnz _b_zero_dec_a 

    ;CANNOT FALL HERE 


_subtract: 
dec a 
dec b 
jnz _dec_a 

;Result 
_result: 
dec c 
0

原来的问题,因为我看到的是:

使用JNZ,INC,DEC,并停止实施ABS(A - B)

我的回答:

不需要使用mov eax命令。只需使用可用命令将结果存储在结果寄存器中即可。 该解决方案将A和B递减,直到其中一个为零,然后将另一个的值设置为RES寄存器并暂停程序执行。 (当程序暂停时,结果将在RES寄存器中)。

我的代码是这样的:

// define/map names to the registers 
#define A R0 
#define B R1 
#define RES R2 

// This solution uses the assumption that A and B are not holding init value of negative numbers values. 

// clear result if not already cleared. 
DEC RES; // in case it was already cleared, this step will prevent counting through all possible values. 
CLEAR_RESULT: 
    INC RES; 
    JNZ CLEAR_RES; 

INC A; // to handle a case of A is initially zero 
INC B; // to handle a case of B is initially zero 

DEC_A: 
    DEC A; 
    JNZ DEC_B; 
    //Now A is zero, and the result is B-1; 
SET_B_TO_RES: 
    INC RES; 
    DEC B; 
    JNZ SET_B_TO_RES; 
    DEC RES; // compensate the incr that was initially done to handle value of 0 (should only be done here...) 
    HALT; 

DEC_B: 
    DEC B; 
    JNZ DEC_A; 
    //Now B is zero, and the result is A; 
SET_A_TO_RES: 
    INC RES; 
    DEC A; 
    JNZ SET_A_TO_RES; 
    HALT; 

// test values: 
// ============= 
// A B 
// 0 2 // A is zero 
// 2 0 // B is zero 
// 1 4 // A is smaller than B 
// 5 2 // B is smaller than A 
// 2 2 // A is equal to B 
相关问题