我現在正在參加大會的本科生課程。我與電訊局長分配我的任務有一些差異。我只是測試進位,零,符號和溢出標誌的狀態。組裝狀態標誌8086
這裏是我錯了標誌狀態問題之一:
mov ah, 255
mov al, -1
cmp ah, al
我的解決方案:CF=0, ZF=1, SF=0, OF=0
他的解決方案:CF=0, ZF=0, SF=1, OF=1
有人可以幫我確認這是正確的?我不認爲我的錯,但如果他們是你能解釋什麼答案是正確的?
我現在正在參加大會的本科生課程。我與電訊局長分配我的任務有一些差異。我只是測試進位,零,符號和溢出標誌的狀態。組裝狀態標誌8086
這裏是我錯了標誌狀態問題之一:
mov ah, 255
mov al, -1
cmp ah, al
我的解決方案:CF=0, ZF=1, SF=0, OF=0
他的解決方案:CF=0, ZF=0, SF=1, OF=1
有人可以幫我確認這是正確的?我不認爲我的錯,但如果他們是你能解釋什麼答案是正確的?
這裏就是我得到的VC 2013(警告,32位內嵌彙編在C++)
3說明之前運行此,該標誌是:
OV = 0 UP = 0 EI = 1 PL = 0 ZR = 0 AC = 0 PE = 0 CY = 0
的3個指令後
OV = 0 UP = 0 EI = 1 PL = 0 ZR = 1 AC = 0 PE = 1 CY = 0
凡標誌寄存器作爲defined here
解釋爲奇偶校驗集,進位未設置,置零,符號未置位,未設置溢出。
這似乎證實您的解決方案。 拆卸我得到:
__asm {
mov ah, 255
00FC13CE mov ah,0FFh
mov al, -1
00FC13D0 mov al,0FFh
cmp ah, al
00FC13D2 cmp ah,al
}
我的8086是非常生疏,但FWIW:
mov
是在文字-1(255)和255不會觸發溢出(未設置標誌)的文字上完成的。255
和-1
。所以我猜測TA可能有複製粘貼錯誤的答案的地方?
謝謝,作業的目標是手工完成,但我很確定電訊管理局未能根據他們所在的範圍和我們正在測試的國旗轉換數字。顯而易見,他沒有用其他方法檢查他的答案。 – Pixel 2014-12-08 04:25:58
您的前兩個項目符號不正確。根據我的回答,'CMP'設置標誌就好像執行了一個'SUB',所以如果有符號/無符號溢出,'CF'和'OF' *都可以被設置。另外,'MOV'不設置任何標誌。無論如何寄存器加載指令永遠不會溢出是沒有意義的。 – 2014-12-08 06:12:19
謝謝 - 我的觀點1確實是錯誤的,第二點是sl。。你的回答非常詳細。 – StuartLC 2014-12-08 06:21:06
你的回答確實是對的。所述Intel Software Developer’s Manual的
卷1描述了每個標誌:
CF(位0)進位標誌 - 如果算術運算產生一個進位或借出most-的設置顯着的結果;否則清除。該標誌表示無符號整數運算的溢出條件。
ZF(位6)零標誌 - 如果結果爲零,則置位;否則清除。
SF(位7)符號標誌 - 設置等於結果的最高有效位,即有符號整數的符號位。 (0表示正值,1表示負值)
OF(位11)溢出標誌 - 如果整數結果太大,表示正數或太小表示負數(不包括符號 - 位)以適應目標操作數;否則清除。該標誌表示有符號整數(二進制補碼)算術的溢出條件。
比較第一源操作數與所述第二源操作數,並設置 狀態標誌中:
在代碼的標誌由
cmp
指令,其中所述指令集第2卷說設置EFLAGS根據結果註冊。比較結果爲 ,通過從第一個操作數中減去第二個操作數,然後以與SUB指令相同的方式設置狀態標誌來執行。SUB指令執行整數減法。它評估 有符號和無符號整數操作數的結果,並設置OF和CF標誌以分別指示 溢出的有符號或無符號結果。 SF標誌指示簽名結果的標誌 。
首先,我們觀察到al
和ah
都具有相同的價值:所有8位1
。
由於CMP
設置了像SUB
這樣的標誌,因此我們只評估0xFF - 0xFF
,這當然是零。
OF,CF - 沒有溢出,所以OF=0
和CF=0
。
ZF - 答案是零,所以ZF=1
。
SF - 答案是零,所以SF=0
。
只是爲了確認,這裏的一些測試代碼(GCC):
標誌。ç
#include <stdio.h>
__attribute__((noinline))
static long test(void)
{
long ret;
asm ("mov $255, %%ah\n\t"
"mov $-1, %%al\n\t"
"cmp %%ah, %%al\n\t"
"pushf\n\t"
"pop %0\n\t"
: "=r" (ret) /* output */
: /* input */
: "%eax" /* clobber */
);
return ret;
}
static void describe_EFLAGS(long flags)
{
printf("EFLAGS: 0x%X\n", flags);
printf(" CF: %d\n", (flags & (1<<0)) > 0);
printf(" PF: %d\n", (flags & (1<<2)) > 0);
printf(" AF: %d\n", (flags & (1<<4)) > 0);
printf(" ZF: %d\n", (flags & (1<<6)) > 0);
printf(" SF: %d\n", (flags & (1<<7)) > 0);
printf(" TF: %d\n", (flags & (1<<8)) > 0);
printf(" IF: %d\n", (flags & (1<<9)) > 0);
printf(" DF: %d\n", (flags & (1<<10)) > 0);
printf(" OF: %d\n", (flags & (1<<11)) > 0);
}
int main(void)
{
long flags = test();
describe_EFLAGS(flags);
return 0;
}
輸出:
$ gcc flags.c && ./a.out
EFLAGS: 0x246
CF: 0
PF: 1
AF: 0
ZF: 1
SF: 0
TF: 0
IF: 1
DF: 0
OF: 0
參考:
你的答案是正確的。如果您正在運行windows,您可以通過打開dos控制檯窗口,運行debug,然後輸入「a100」來手動輸入指令來驗證這一點:mov ah,ff | mov al,ff | cmp啊,al | nop | |,然後g = 100,106來運行代碼。它將顯示標誌爲:NV(OF = 0),...,PL(SF = 0),ZR(ZF = 1),NC(CF = 0)。輸入q退出調試。如果你想知道PE是偶校驗(PF = 1),PO是奇校驗(PF = 0)。 –
rcgldr
2014-12-08 04:13:10