1. 程式人生 > >linux-AT&T彙編,把32位暫存器的值以16進位制字串打印出來

linux-AT&T彙編,把32位暫存器的值以16進位制字串打印出來

將暫存器的值以16進位制顯示,程式如下:

.section .bbs
.lcomm buf,10 #定義一個10位元組長度的記憶體區,用來儲存計算出來的字元

.section .text
.globl _start
_start:
//初始化暫存器
movl $0x01abcdef,%eax #將需要轉換的值存入eax
movl $0,%edi
movl $0x0000000f,%edx
//寫入‘0X’
movl $0x30,(buf)
movl $0x58,(buf+1)

//迴圈計算字元
loop_ascii:
movl %eax,%ebx
imul $4,%edi,%ecx
and %edx,%ebx
ror %cl,%ebx
cmpb $10,%bl
jnc max9
addb $0x30,%bl
jmp fun
max9:
addb $0x37,%bl
fun:
rol $4,%edx
movl $9,%ecx
sub %edi,%ecx
movb %bl,buf(,%ecx,1)
cmp $7,%edi
jnc print
inc %edi
jmp loop_ascii

//輸出
print:
movl $1,%ebx
movl $4,%eax
movl $buf,%ecx
movl $10,%edx
int $0x80
//退出程式
movl $0,%ebx
movl $1,%eax
int $0x80

執行結果如下:


彙編程式與其他高階程式語言的程式設計思路不同,所以如果純粹用函式程式設計的思想反而會搞得很麻煩,例如:

/*計算以下方程式:x=5
*y=2*x,x>=4
*y=1+x,x<4
*將值存入ebx
*/
.section .text
.globl _start
_start:
movl $5,%ebx #初始化ebx
cmp $4,%ebx #比較ebx的值
jnc fun1 #如果ebx大於等於4,就跳轉到標號fun1處,計算2*ebx
addl $1,%ebx  #否則計算1+ebx
jmp exit #如果沒有這句話,程式會接著執行fun1的語句,所以儘量不要把標號看作函式名來使用

fun1:
imul $2,%ebx,%ebx 
//退出程式,返回值為ebx中的值
exit:
movl $1,%eax
int $0x80

執行結果:


下圖可以直觀反映該程式的結構:


系統會從1開始依次向後執行,遇到跳轉語句時跳轉到指定的位置,接著向後執行,標號並不反映在執行程式中。