movzbl和movsbl
匯編語言中最最常用的指令 -- 數據傳送指令,也是我們接觸的第一種類別的匯編指令。其指令的格式為:“mov 源操作數, 目的操作數”。
mov系列支持從最小一個字節到最大雙字的訪問與傳送。其中movb用來傳送一字節信息,movw用來傳送二字節,即一個字的信息,movl用來傳送雙字信息。這些不詳說了。除此以外mov系列還提供兩個帶位擴展的指令movsbl和movzbl,我們舉個例子來說明一下這兩個特殊指令的作用何在:
a) movzbl指令
void dummy1() {
?unsigned char c = 'a';
?unsigned int a = c;
}
其對應的GNU匯編為(省略部分內容):
?movb?$97, -1(%ebp)?? //'a'的ASCII碼為97
?movzbl?-1(%ebp), %eax
?movl?%eax, -8(%ebp)
說明:在dummy1函數中“unsigned int a = c”語句完成的是一個從unsigned char到unsigned int的賦值操作,由于int的類型長度大于char類型長度,所以實際是將一個字節的內容拷貝到一個可以容納4個字節的地方,這樣的話需要對源數據進行一下擴展,即填充高位的3個字節。
如何填充呢?由于變量a和c都為無符號整型,所以只需要填充0即可。而movzbl就是干這個活的。movzbl指令負責拷貝一個字節,并用0填充其目的操作數中的其余各位,這種擴展方式叫“零擴展”。
b) movsbl指令
void dummy2() {
?signed char c = 'a';
?unsigned int a = c;
}
其對應的GNU匯編為(省略部分內容):
?movb?$97, -1(%ebp)?? //'a'的ASCII碼為97
?movsbl?-1(%ebp), %eax
?movl?%eax, -8(%ebp)
說明:在dummy2函數中“unsigned int a = c”語句完成的是一個從signed char到unsigned int的賦值操作,由于int的類型長度大于char類型長度,所以實際是將一個字節的內容拷貝到一個可以容納4個字節的地方,這樣的話需要對源數據進行一下擴展,即填充高位的3個字節。如何填充呢?GNU匯編告訴我們它使用了變量c的最高位來填充其余的3個字節。movsbl指令負責拷貝一個字節,并用源操作數的最高位填充其目的操作數中的其余各位,這種擴展方式叫“符號擴展”。實際上dummy2中變量a還是保留了變量c的符號位的,起碼GCC是這么做的。
c) 在CS.APP中pushl和popl也別歸入“數據傳送指令”類別,但對于剛入門選手這兩個指令還是稍顯復雜,在以后談到“procedure”時再細說。
轉載于:https://www.cnblogs.com/johnnyflute/p/3597352.html
總結
以上是生活随笔為你收集整理的movzbl和movsbl的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows 8的无线设置后,竟不能直
- 下一篇: vim - 查找替换