gpt4 book ai didi

c - 在此汇编代码中如何设置进位标志?

转载 作者:太空宇宙 更新时间:2023-11-04 05:24:35 25 4
gpt4 key购买 nike

给定以下 16 位 PRNG 函数的汇编代码,

$80/8111 E2 20       SEP #$20   ; set 8-bit mode accumulator
$80/8113 AD E5 05 LDA $05E5 ; load low byte of last random number
$80/8116 8D 02 42 STA $4202
$80/8119 A9 05 LDA #$05 ; multiply it by 5
$80/811B 8D 03 42 STA $4203
$80/811E EA NOP
$80/811F C2 20 REP #$20 ; set 16-bit mode accumulator
$80/8121 AD 16 42 LDA $4216 ; load the resultant product
$80/8124 48 PHA ; push it onto the stack
$80/8125 E2 20 SEP #$20 ; 8-bit
$80/8127 AD E6 05 LDA $05E6 ; load high byte of last random number
$80/812A 8D 02 42 STA $4202
$80/812D A9 05 LDA #$05 ; multiply by 5
$80/812F 8D 03 42 STA $4203
$80/8132 EB XBA ; exchange high and low bytes of accumulator
$80/8133 EA NOP
$80/8134 AD 16 42 LDA $4216 ; load low byte of product
$80/8137 38 SEC
$80/8138 63 02 ADC $02,s ; add to it the high byte of the original product
$80/813A 83 02 STA $02,s ; save it to the high byte of the original product
$80/813C C2 20 REP #$20 ; 16-bit
$80/813E 68 PLA ; pull it from the stack
$80/813F 69 11 00 ADC #$0011 ; add 11
$80/8142 8D E5 05 STA $05E5 ; save as new random number
$80/8145 6B RTL

一个叫@sagara 的用户将代码翻译成 C:

#define LOW(exp)  ((exp) & 0x00FF)
#define HIGH(exp) (((exp) & 0xFF00) >> 8)

uint16_t prng(uint16_t v) {

uint16_t low = LOW(v);
uint16_t high = HIGH(v);

uint16_t mul_low = low * 5;
uint16_t mul_high = high * 5;

// need to check for overflow, since final addition is adc as well
uint16_t v1 = LOW(mul_high) + HIGH(mul_low) + 1;
uint8_t carry = HIGH(v1) ? 1 : 0;

uint16_t v2 = (LOW(v1) << 8) + LOW(mul_low);

return (v2 + 0x11 + carry);
}

我对两件事感到困惑。

  1. 在这一行...

    uint16_t v1    = LOW(mul_high) + HIGH(mul_low) + 1;

    为什么会有 + 1?我认为这是因为 ADC 操作,但我们如何确定进位标志设置为 1? 之前的什么操作可以保证这一点? XBC?我读了一些帖子,例如 Assembly ADC (Add with carry) to C++Overflow and Carry flags on Z80 但我不清楚,因为 指令集似乎不同 我不熟悉 65C816 assembly 。 (这是来自一款流行的 1994 年 SNES 游戏,其 NA 发布周年纪念日刚刚过去;免费投票给正确的猜测:-)

  2. 在下一行...

    uint8_t  carry = HIGH(v1) ? 1 : 0;

    为什么会这样?我读它是这样的,“当且仅当高字节不为零时才设置进位标志。”但是只有当高字节 零?(我可能误解了这条线在做什么。)

提前感谢您的任何见解。

最佳答案

  1. but how can we be sure that the carry flag is set to 1? What previous operation would guarantee this?
$80/8137 38          SEC   ; SEt Carry flag

  1. uint8_t carry = HIGH(v1) ? 1 : 0;
    Why would it work this way? I read this as, "Set the carry flag if and only if the high byte is non-zero." But wouldn't the indication of an overflow be only if the high byte is zero?

加法 ADC#$0011 使用来自 ADC $02,s 的进位。当执行 ADC $02,s 时,累加器设置为 8 位(因为 SEP #$20),因此如果 的结果将设置进位标志code>ADC $02,s 将超过 8 位(即,如果您在 16 位模式下得到 >= $100 的东西)。
在 C 版本中,您有一个 16 位变量 (v1) 来保存结果,因此您的进位将位于 v1 的第 8 位,您可以对其进行测试HIGH(v1) == 1,或者只是 HIGH(v1) 因为它要么是 1 要么是 0。

关于c - 在此汇编代码中如何设置进位标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36745601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com