汇编 —— AT&T小练习

这篇博客介绍了AT&T汇编语言的一些实践,包括堆栈工作原理、函数调用的call指令、loop指令的使用、for循环实现、if分支处理、长整型数据处理、溢出分析以及右移与除法的区别。同时,讨论了负数左移和右移的行为,并展示了如何通过控制浮点精度来优化计算速度。
摘要由CSDN通过智能技术生成

堆栈是向下拓展的

一个很简单的例子,将两个32字节的数字压入堆栈,查看esp堆栈寄存器前后的变化。

.section .text
.global main
main:
    nop
    pushl $1
    pushl $2

调试查看:

[edemon@CentOS workspace]$ gcc -gward -o pushpop pushpop.s 
[edemon@CentOS workspace]$ gdb pushpop
...
(gdb) b *main+1
Breakpoint 1 at 0x80483ed: file pushpop.s, line 5.
(gdb) r
Starting program: /home/edemon/workspace/pushpop 

Breakpoint 1, main () at pushpop.s:5
5       pushl $1

(gdb) p $esp
$5 = (void *) 0xbffff4dc
(gdb) n
main () at pushpop.s:6
6       pushl $2
(gdb) n
0x080483f1 in main ()
(gdb) p $esp
$6 = (void *) 0xbffff4d4

可以发现前后的esp寄存器地址值相差8,且数值变小。

函数调用call

用简单的函数调用计算2^4

.section .data
result:
    .asciz "the result is %d\n"
.section .text
.globl main
main:
    nop
    movl $2,%eax
    call func
    call func
    call func
    pushl %eax
    pushl $result
    call printf
    pushl $0
    call exit
func:
    pushl %ebp
    movl %esp,%ebp
    add %eax,%eax
    movl %ebp,%esp
    popl %ebp
    ret

loop

loop指令自动使用ECX寄存器作为计数器,每一次迭代过程中递减并测试这个计数器。
下面的程序用于计算2^5:

# calculate 2^5
.section .data
output:
    .asciz "2^5 is %d\n"
.section .text
.global main
main:
    movl $4,%ecx
    movl $2,%ebx
    myloop:
    addl %ebx,%ebx
    loop myloop
    pushl %ebx
    pushl $output
    call printf
    addl $8,%esp        #clear stack
    movl $0,%ebx        
    movl $1,%eax        #sys_exit
    int $0x80

for循环

计算前20位的斐波纳契
代码:

.section .data
values:
    .int 1,1
#output:
#    .asciz "num = \n"
.section .text
.globl main
main:
    nop
    movl $0,%ecx
    loop:
        movl $0,%eax               #eax is next feibo element.
        add values(,%ecx,4),%eax
        add $1,%ecx
        add values(,%ecx,4),%eax
        add $1,%ecx
        movl %eax,values(,%ecx,4)
        sub $1,%ecx
        cmp $18,%ecx               #if ecx < 18
        jle loop
    nop

gdb查看内存:

[edemon@CentOS workspace]$ gdb feibo1
(gdb) b 21
Breakpoint 1 at 0x804841a: file feibo1.s, line 21.
(gdb) r
Starting program: 

Breakpoint 1, loop () at feibo1.s:21
21      nop
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.i686
(gdb) x/20 &values
0x8049684 <values>: 1   1   2   3
0x8049694 <completed.6190>: 5   8   13  21
0x80496a4:  34  55  89  144
0x80496b4:  233 377 610 987
0x80496c4:  1597    2584    4181    6765

if分支

写一个简单的if分支语句,用于处理1和2的比较。

.section .data
str1:
    .asciz "1 <= 2."
    len1 = . - str1
str2:
    .asciz "1 > 2."
    len2 = . - str2
.section .text
.global main
main:
    movl $1,%ecx
    movl $2,%edx
    cmpl %edx,%ecx
    jle L1
    movl $len2,%edx
    movl $str2,%ecx
    jmp end
L1:
    movl $len1,%edx
    movl $str1,%ecx
    jmp end
end:
    movl $1,%ebx              
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值