IMUL、MUL和div的用法
MUL是進行無符號乘法的指令。MUL(無符號乘法)指令有三種格式:第一種是將8位的操作數於al相乘。第二種是將16位的操作數與ax相乘; 第三種是將32位的操作數與eax進行相乘
乘數和被乘數大小必須相同,乘積的尺寸是乘數/被乘數大小的兩倍。 三種格式都既接受寄存器操作數,也接受內存操作數。但是不接受立即操作數(這點大家注意下)。
例如:
你想將al寄存器中的值乘上2,那麼此時你需要將立即數2存放到一個寄存器中,然後通過mul指令相乘,或者將立即數放到一個內存地址中,然後通過內存單元的形式來進行相乘。
舉例:
mov bl, 2
mul bl ;此刻將bl寄存器中的值乘上al寄存器中的值
指令中唯一的一個操作數是乘數。
也就是當我們的乘數是8位的時候,則與al相乘,如果我們的乘數是16位則與ax相乘,如果我們的乘數是32位則與eax寄存器相乘。
那麼下面我給出mul乘法的相關操作數的實例
被乘數 乘數 積
al 8位操作數 ax
ax 16位操作數 dx:ax
eax 32位操作數 edx:eax
因為如果我們的乘數是一個8位操作數的話,我們的結果存在在ax寄存器中。 如果是16位操作數的話,我們的結果存放在dx:ax中。如果dx不為0,則進位標誌置位。
在執行完mul指令後,我們一般要檢查下進位標誌。因為我們需要知道乘積的高半部分是否可以安全的忽略。
例如:
mov al, 6h
mov bl, 10h
mul bl
此刻我們檢查進位標誌cf = 0, 那麼ah我們就可以將其忽略了,所以結果是60h。
那麼我們再來舉一個例子:
例如:
mov ax, 6000
mov bx, 5000
mul bx
我們檢查進位標誌,此時cf = 1。 那麼我們的結果是dx:ax ,此時我們的dx = 1E00, ax = 0000 所以 最後我們的積 為 1E000000。
其實我們從乘積就可以算出來cf是否置位了。
1.接下來我們留個小作業,不要用其他輔助工具來計算。自己口算下,執行完後,積為多少?
mov eax, 00800000
mov ebx, 00200000
mul ebx
彙編基礎一日一學習31 IMUL
大家好,今天我們來學習下有符號整數的乘法運算,IMUL指令。這個指令保留了乘積的符號位。IMUL指令,IA - 32指令集中有三種格式: 單操作數、雙操作數和三操作數。 在單操作數格式中,乘數和被乘數尺寸大小相同,乘積的大小是乘數/被乘數大小的兩倍。
單操作數格式: 單操作數格式把乘積存儲在累加器( ax, dx:ax, edx:eax)中。imul指令單操作數格式其實和我們昨天學習的mul指令格式基本一樣。
1.那麼接下來我們來看下IMUL單操作數的格式:
imul 8位寄存器/8位內存操作數
imul 16位寄存器/16位內存操作數
imul 32位寄存器/32位內存操作數
2.雙操作數數格式:
imul 16位寄存器/ 16位寄存器-16位內存操作數
imul 16位寄存器/ 8位立即數
imul 16位寄存器/ 16位立即數
從上面我們可以看出 雙操作數格式中,乘積存儲在第一個操作數中,第一個操作數必須是寄存器,第二個操作數可以是寄存器、內存操作數、或立即數。 上面雙操作數我是按照16位來給大家舉的一些例子。 它當然還可以是32位的。
imul 32位寄存器/ 32位寄存器-32位內存操作數
imul 32位寄存器/ 8位立即數
imul 32位寄存器/ 32位立即數
3.三操作數格式:
imul 16位寄存器/ 16位寄存器-16位內存操作數/ 8位立即數
imul 16位寄存器/ 16位寄存器-16位內存操作數/ 16位立即數
三操作數格式把乘積存儲在第一個操作數,一個16位寄存器可以被一個8位或者16位的立即數乘。
imul 32位寄存器/ 32位寄存器 -32位內存操作數/ 8位立即數
imul 32位寄存器/ 32位寄存器 -32位內存操作數/ 32位立即數
如果有效位丟失,則溢出標誌和進位標誌置位。 使用三操作數格式時,一定要在執行完imul操作後檢查相關操作位。
好,光看理論估計你很迷糊,那麼我們就來看幾個實例:
1. 例如 mov al, -3
mov bl, 6
imul bl
此刻執行的時候(-3*6)的結果存放到ax寄存器中,由於上面我說了,在執行imul進行有符號整數的乘法運算時,保留了乘積的符號位,也就是說乘積的高半部分是低半部分的符號擴展。 符號擴展是什麼意思呢? 也就是說 如果我們的乘積是個負數則,高半部分都為1,如果乘積是個正數的話,高半部分都為0。很顯然我們(-3*6)是負數,所以此時高半部分肯定是1,不信大家來計算下。
-3的16進位表示形式是0FDh
好此刻我們將0FD轉換成補碼的形式,大家不知道還記得16進位整數轉換補碼的方法嗎,用15減去各個進位位,最終結果+1。
此刻
FDh
15 - F = 0
15 - D = 2
+ 1 = 03h
03*6h = 12h (注意10進位18 = 16進位12h)
此刻我們將取12h的補碼則為我們最後的乘積
12h
15 - 1 = E
15 - 2 = D
+ 1 = EEh
由於EEh的最高符號位是1,所以此時高半部分將擴展為低半部分的符號位,所以此時高半部分為FF(也就是全是二進位位1)。
最終的結果是FFEEh,此時由於已經被擴展了,所以此時的of = 0。(也就是說如果沒有擴展的話,of = 1)。
2.再來看個例子
mov al, 3h
mov bl, 6h
imul bl
大家口算就可以算的出來,很顯然3*6=18, 16進位 = 12h, 此時由於結果為正,因為結果是12h,但是我們也並不能通過of 或者是 if來指示乘積的高半部分是否為0,也就是說我們的imul雖然能進行無符號整數運算,但是我們不能通過它影響的標誌位來進行判斷。。
3. 再來看個例子
mov al, 48
mov bl, 3
imul bl
很顯然我們的結果為正數,得到的積+144存放在ax中,由於ah不是al的符號擴展,因為溢出標誌位置位。 of =1
4. 那麼接下來我再來舉個2操作數的。
mov ax, -30h
mov bx, 10h
imul ax, bx
那麼-30 * 10 = -48 * 16 = -768
= -300h
然後我們求反碼
300
15 - 3 = C
15 - 0 = F
15 - 0 = F
+ 1 = D00
因為我們的結果是負數,因為我們的結果是存在ax寄存器中的,而由於上面說了有符號數值的乘積是帶符號位擴展的,高4位應該全是1填充,所以最終結果為FD00h
5.接下來我們來個3位操作數的。
mov ax, -30h
imul bx, ax, 2h
這三個操作數的是將結果存放在第一個操作數中。
-30 * 2 = -60
這時候取反碼
15 - 6 = 9
15 - 0 = F
+1 = A0
乘積 = FFA0h,存放到bx中。
留個作業:
1.
mov ax, -60h
imul bx, ax, 3
問:乘積多少?
彙編基礎一日一學習32 DIV
大家好,今天我們來學習下無符號整數的除法運算指令,div(無符號)指令執行8位、16位和32位無符號整數的除法運算。指令中必須是唯一的一個寄存器或內存操作數是除數。
div指令格式:
div 8位寄存器/8位內存操作數
div 16位寄存器/16位內存操作數
div 32位寄存器/32位內存操作數
div指令格式和我們的mul基本可以算作是相反的。那麼我們看下被除數 、 除數、商、餘數之間的關係。
被除數 除數 商 餘數
ax 8位寄存器/8位內存操作數 al ah
dx:ax 16位寄存器/16位內存操作數 ax dx
edx:eax 32位寄存器/32位內存操作數 eax edx
1.
舉個例子:
mov ax, 0060h
mov bl, 2
div bl ;al = 30h , ah = 00h
那麼執行完後, 商是30h ,餘數是00h
2.
在舉個例子
執行(6005h/100h),由於我們的出示是16位,所以被除數是放在dx:ax中的。 但是由於被除數是6005h,所以我們必須將dx清0.
xor dx, dx
mov ax, 6005h
mov bx, 100h
div bx
那麼執行後, 我們的ax = 0060h, dx = 0005h。 所以我們的商是60h, 餘數是5h。
很簡單。
※gcc g加加 make cmake區別
※Docker下安裝開源看板Xibo
TAG:程序員小新人學習 |