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

运行结果如下:

linux-AT&T汇编,把32位寄存器的值以16进制字符串打印出来_第1张图片

汇编程序与其他高级编程语言的编程思路不同,所以如果纯粹用函数编程的思想反而会搞得很麻烦,例如:

/*计算以下方程式: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

运行结果:

linux-AT&T汇编,把32位寄存器的值以16进制字符串打印出来_第2张图片

下图可以直观反映该程序的结构:

linux-AT&T汇编,把32位寄存器的值以16进制字符串打印出来_第3张图片

系统会从1开始依次向后执行,遇到跳转语句时跳转到指定的位置,接着向后执行,标号并不反映在执行程序中。

你可能感兴趣的:(汇编)