下面是我为64位英特尔程序集使用GAS语法编写的代码示例。运行代码时,期望在_print子例程中打印出字符串:。
#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‘作为写系统调用的第三个参数时,在屏幕上打印消息之后,我会得到一些奇怪的额外字符:
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)将被写入标准输出。
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ ./subroutine
Inside the _print subroutine.
ali@alix2:~/Programming/asm/GAS-Syntax/SubRoutine$ 有人能解释一下背后的原因吗?谢谢。
发布于 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中。
https://stackoverflow.com/questions/61191024
复制相似问题