Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
564 views
in Technique[技术] by (71.8m points)

as intel汇编如何引用.bss的变量

# 目的: 读取一个文件的内容到buffer
.intel_syntax noprefix
.equ SYSEXIT, 0x3c
.equ SYSREAD, 0
.equ SYSOPEN, 2

# 打开文件的选项见/usr/include/asm-generic/fcntl.h, 允许选项叠加
.equ O_RDONLY, 0

.equ BUFFER_SIZE, 500

.section .bss
.lcomm BUFFER_DATA, BUFFER_SIZE

.section .text

# 栈位置
.equ ST_SIZE_RESERVE, 8 # 描述fd大小
.equ ST_FD_IN, -8
.equ ST_FD_OUT, -16
.equ ST_ARGC, 0 # 参数个数
.equ ST_ARGV_0, 8 # 程序名
.equ ST_ARGV_1, 16 # 输入文件名
.equ ST_ARGV_2, 24 # 输出文件名

.globl _start
_start:
mov rbp, rsp

# linux开始时, 所有指向命令行参数的指针都存储在栈中, 参数个数在[rsp], 程序名在[rsp+8], 参数在[rsp+16]及之后的存储位置, 指针指向的字符串参数以``结尾.
open_files: # symbol不影响代码程序运行, 仅在程序跳转时有用
open_fd_in: # 打开文件, 会将fd结果放入rax
    mov rax, SYSOPEN
    mov rdi, QWORD PTR [rbp+ST_ARGV_1] # 获取输入文件名
    mov rsi, O_RDONLY # 打开选项
    mov rdx, 0 # 权限, 不影响实际的读操作
    syscall

    push rax # 保存输入文件的fd

read_loop_begin: # 开始读取文件
    mov rax, SYSREAD
    mov rdi, QWORD PTR [rbp+ST_FD_IN] # rbx放入fd
    mov rsi, BUFFER_DATA # rsi保存缓冲区地址
    mov rdx, BUFFER_SIZE # rdx保存缓冲区大小
    syscall

    mov rdi, rax
    mov rax, SYSEXIT # 退出
    syscall

运行:

$ as --64 s.s -o a.o
$ ld a.o
$ gdb --args ./a.out in.txt // in.txt有12个ascii
(gdb) b _start
Breakpoint 1 at 0x401000
(gdb) r
Starting program: /home/chen/git/learn_asm/example/s.out 5.in.txt

Breakpoint 1, 0x0000000000401000 in _start ()
(gdb) si 12
0x000000000040103b in read_loop_begin ()
(gdb) disassemble // att语法
Dump of assembler code for function read_loop_begin:
   0x000000000040101f <+0>:    mov    $0x0,%rax
   0x0000000000401026 <+7>:    mov    -0x8(%rbp),%rdi
   0x000000000040102a <+11>:    mov    0x402000,%rsi
   0x0000000000401032 <+19>:    mov    $0x1f4,%rdx
   0x0000000000401039 <+26>:    syscall 
=> 0x000000000040103b <+28>:    mov    %rax,%rdi
   0x000000000040103e <+31>:    mov    $0x3c,%rax
   0x0000000000401045 <+38>:    syscall 
End of assembler dump.
(gdb) p /x $rsi
$1 = 0x0

实际读取结果不对, 调试发现: mov rsi, BUFFER_DATA 被编译成了 mov 0x402000,%rsi, 此时rsi是0, 因为取的是BUFFER_DATA(0x402000)头8B的内容, 请问要引用BUFFER_DATA得怎么写?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

使用lea rsi, BUFFER_DATA即可.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...