第18部分-Linux x86 64位汇编 AT&T实现栈

第18部分-Linux x86 64位汇编 AT&T实现栈

我们根据上篇中AT&T汇编语法改造之前栈篇的代码如下。

主要好处是通过as编译后,可以通过gdb进行debug。

.section .data
    .equ SYS_WRITE,1
    .equ STD_IN,1
    .equ SYS_EXIT,60
    .equ EXIT_CODE,0

    .equ NEW_LINE,0xa
    WRONG_ARGC: .ascii "Must be two command line argument\n"

.section .text
    .global _start

_start:
    pop %rcx ;//栈的第一个保存的是参数的数量,数量不为3则跳转到argcError处退出。
    cmp $3, %rcx ;//两个参数,外加一个程序名,程序名也是参数。
    jne argcError

    addq $8, %rsp;//[rsp+8]保存的是第一个参数argv[0],跳过程序名这个变量。
    popq %rsi;//将第一个参数赋值给rsi。
    call str_to_int;//调用函数str_to_int,将参数转换为整型,保存于rax。
    movq %rax, %r10; //保存到r10寄存器中
    popq %rsi; //将第二个参数赋值为rsi
    call str_to_int; //调用函数str_to_int,字符串保存的,例如“123\0”
    movq %rax,%r11; //保存到r11寄存器中
    addq %r11, %r10; //完成加法。
    movq %r10, %rax
    xor %r12, %r12
    jmp int_to_str; //调用函数int_to_str函数,整型转换为字符串

argcError:
    movq     $1,%rax
    movq     $1,%rdi
    movq     $WRONG_ARGC, %rsi
    movq    $34, %rdx
    syscall
    jmp exit

str_to_int:; //负责将字符串转换为整型
    xor %rax, %rax; //清空rax寄存器
    movq $10,%rcx; //赋值rcx为10
next:
    cmpb $0,(%rsi); //对比参数的低位字节,是否为0,字符串最后一个为’\0’。
    je return_str; //为0,则调用函数return_str返回。
    movb (%rsi),%bl; //否则将低8位赋值给bl。
    subb $48, %bl; //参数减去48,ASCII码中,字符和数字相差48。
    mulq %rcx; //乘以10,将已处理的字符往高位挪。
    addq %rbx, %rax;
    inc %rsi; //增加rsi,即变为下一个字节。
    jmp next; //调到函数next

return_str:
    ret; //直接返回。

int_to_str:
    movq $0, %rdx
    movq $10, %rbx
    divq %rbx; //除以10,获取个位数余数在rdx,商在rax。
    addq $48,%rdx
    ;addq $0x0,%rdx
    pushq %rdx
    inc %r12; //首次迭代为0,记录字符的个数,用于后续输出。
    cmp $0x0,%rax; //商是否为0,为0则退出,跳转到print进行输出。
    jne int_to_str; //商不为0,则继续输出。
    jmp print

print:
    movq $1,%rax
    mulq %r12
    movq $8,%rax;//计算长度,因为入栈是8个字节一次的,所以每个字符输出都是8个字节了
    mulq %r12
    movq %rax,%rdx

    movq $SYS_WRITE,%rax
    movq $STD_IN,%rdi
    movq %rsp,%rsi
    syscall; //调用sys_write输出结果
jmp exit

exit:
    movq $SYS_EXIT,%rax
    movq $EXIT_CODE,%rdi
    syscall

编译:

# as -g -o addsum_att.o addsum_att.s

#ld  -o addsum_att addsum_att.o

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值