不懂移位、旋转和 LAHF

Don't understand shifting, rotating, and LAHF

例如,这是我的作业

Write an HLA Assembly program that prompts for an int8 value to inspect and then prints it in binary format. For example, here would be the program output for various entered values

Gimme a decimal value to print: 15
15 is 0000_1111
Gimme a decimal value to print: 7
7 is 0000_0111

我能够获得答案的源代码,但我无法理解。

我把我的思考过程放在评论里

 program binaryoutput;
 #include( "stdlib.hhf" );
 static
   zGivenNumber : int8;  // the value to inspect
 begin binaryoutput;
    //Ask for a decimal number
    stdout.put( "Gimme a decimal value to print: ");
    //Put that number in 'zGivenNumber' (Let's say 7)
    stdin.get( zGivenNumber );
    //Put 'zGivenNumber' inside 'BH' ('BH' now contains 7)
    mov( zGivenNumber, BH);

    stdout.put("Number in binary is: ", nl);

    //Shift left 1 at 'BH' (This makes 'BH' 14)
    shl(1, BH);
    //Not a clue what this is doing
    lahf();
    //Checking to see if 0000_0001 and AH match 0's and 1's
    //(I'm not sure about the % sign as well as where AH came from)
    and( %0000_0001, AH );
    //Print out 'AH' in Eight Bit form
    stdout.puti8(AH);

    shl(1, BH); //2
    lahf();
    and( %0000_0001, AH );
    stdout.puti8(AH);

    shl(1, BH); //Next
    lahf();
    and( %0000_0001, AH );
    stdout.puti8(AH);
    shl(1, BH); //Next
    lahf();
    and( %0000_0001, AH );
    stdout.puti8(AH);
    stdout.put("_");
    shl(1, BH); //Next
    lahf();
    and( %0000_0001, AH );
    stdout.puti8(AH);
    shl(1, BH); //Next
    lahf();
    and( %0000_0001, AH );
    stdout.puti8(AH);
    shl(1, BH); //Next
    lahf();
    and( %0000_0001, AH );
    stdout.puti8(AH);
    shl(1, BH); //Next
    lahf();
    and( %0000_0001, AH );
    stdout.puti8(AH);

 end binaryoutput;

我们还不允许使用循环。

我想我不明白 shl 和 LAHF 部分

据我了解,LAHF 的意思是从 Flags 加载 AH。所以这会将标志放入 AH。这就是 AH 的来源,这是有道理的。此外,shl 将 0 放入第 0 位,然后将第 7 位中的内容转移到进位标志中。但我只是不确定那是什么意思。

lahf 只是将 cpu 标志加载到 ax 寄存器 (ah) 的高位字节。标志位 0(和 lahf 指令后的 ah)是进位标志。因此,如果 bh 的 msb 为 1,则在左移后将设置进位。基本上这只是从 bh.

从 msb 到 lsb 弹出位

https://whosebug.com/tags/x86/info 标签 wiki 有指向英特尔指令参考手册和许多其他好东西的链接。如果您不知道 LAHF 的作用,为什么不查一下呢?

此外,您可以直接使用进位标志,而不是搞乱 LAHF。 (x86 移位指令设置 CF = 移出的最后一位,您在 HLA 评论中没有提到。)

shl  bh, 1
setc al
add  al, '0'   ; AL = '0' or '1', depending on the last bit shifted out of bh

xor  eax,eax    ; have to zero AL every time, but if you want to get fancy you can then use AL and AH, and then store two digits from AX.
shl  bh, 1
adc  al, '0'    ; AL = '0' + the last bit shifted out of BH

进位标志比较特殊,有adc / sbb / rcr / rcl 之类的指令与之交互,以及通常的 setcc.