首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在GAS中进行系统调用,并在.data部分中使用变量,并在另一个子例程中访问系统调用。

在GAS中进行系统调用,并在.data部分中使用变量,并在另一个子例程中访问系统调用。
EN

Stack Overflow用户
提问于 2020-04-13 15:19:18
回答 1查看 106关注 0票数 0

下面是我为64位英特尔程序集使用GAS语法编写的代码示例。运行代码时,期望在_print子例程中打印出字符串:。

代码语言:javascript
复制
#This example is a an example to call a subroutine 
.global _start

.section .text

_start:

    call _print

_exit:   
    #exit call
    mov $60, %rax
    xor %rdi, %rdi

    syscall

_print:
    #set up the stack frame
    push %rbp
    mov %rsp, %rbp

    # write syscall's parameter set up
    mov std_out_fd, %rdi
    mov $message, %rsi
    movq message_size, %rdx
    mov write_syscall_no, %rax

    syscall

    #Restore callers registers value
    #pop %rdx
    #pop %rsi
    #pop %rdi 

    #Destroy the stack frame:
    mov %rbp, %rsp
    pop %rbp

    ret


.section .data


std_out_fd: .int 0x02

message: .ascii "Inside the _print subroutine.\n"

message_size: .byte 30

write_syscall_no: .int 0x01

=========================================

当我尝试使用声明的变量'message_size‘作为写系统调用的第三个参数时,在屏幕上打印消息之后,我会得到一些奇怪的额外字符:

代码语言:javascript
复制
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ as -o subroutine.o subroutine.s
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ ld -o subroutine subroutine.o
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ ./subroutine
Inside the _print subroutine.
`;`Qali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$

但是当我没有使用变量时,我将它改为mov $30,%rdx

然后,它完美地工作,没有任何额外的字符(;,q)将被写入标准输出。

代码语言:javascript
复制
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ ./subroutine
Inside the _print subroutine.
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ 

有人能解释一下背后的原因吗?谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-13 15:37:06

movq message_size, %rdx是包含.byte 30.int 0x1的64位(qword)加载,超过该加载数为3个字节。使用调试器(例如GDB)查看寄存器中的值。并使用strace ./subroutine跟踪系统调用,并显示您正在向write传递一个很大的长度。

您可以使用movzbl message_size(%rip), %edx负载将该字节零扩展到RDX中。

或更高版本,让汇编程序用计算汇编时间常数的大小。

.equ message_size, . - message,以便您可以使用$message_size作为即时。不需要分别对大小进行硬编码或将其存储在数据内存中。

对于呼叫号码也是如此;不要对其执行64位的加载,特别是不使用32位.int!如果您在.data中有任何其他内容,那么它将将垃圾加载到RAX的高字节中。您可以直接将mov扩展到EAX,其中零扩展到RAX中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61191024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档