首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FreeBSD/amd64汇编-如何阅读"ARGC"?

FreeBSD/amd64汇编-如何阅读"ARGC"?
EN

Stack Overflow用户
提问于 2011-11-18 12:21:29
回答 2查看 641关注 0票数 4

有时返回正确的值,有时返回0,有时(看似)随机数……都来自同一个可执行文件。

代码语言:javascript
复制
.section .text
.global _start
_start:
    movq    $1, %rax
    popq    %rdi
    syscall

例如:

代码语言:javascript
复制
%as -o this.o this.s ; ld -o this this.o

%./this; echo $?
1

%./this 1; echo $?
0

%./this 1 2; echo $?
3

%./this 1 2 a; echo $?
4

%./this 1 2 a f; echo $?
0

%_

我还是个汇编语言新手,但我很有信心,获取参数计数就像从堆栈中弹出一样简单。是我做错了什么,还是真的搞砸了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-14 15:38:47

我在FreeBSD 9.0/amd64上也遇到了同样的问题。我所做的是(我使用nasm进行汇编):

代码语言:javascript
复制
$ cat foo.asm
global _start
_start:
        mov     rax, 4          ; write
        mov     rdi, 1          ; stdout
        mov     rsi, rsp        ; address
        mov     rdx, 16         ; 16bytes
        syscall

        mov     rax, 1          ; exit
        syscall
$ nasm -f elf64 foo.asm && ld -o foo foo.o
$ ./foo | hd
00000000  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|
00000010
$ ./foo 2 | hd
00000000  02 00 00 00 00 00 00 00  b8 dc ff ff ff 7f 00 00  |................|
00000010
$ ./foo 2 3 | hd
00000000  00 00 00 00 00 00 00 00  03 00 00 00 00 00 00 00  |................|
00000010
$ ./foo 2 3 4 | hd
00000000  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00000010
$ ./foo 2 3 4 5 | hd
00000000  05 00 00 00 00 00 00 00  b0 dc ff ff ff 7f 00 00  |................|
00000010

我本以为argc在rsp,但事实并非如此。

我猜是内核(映像激活器)设置了寄存器。我搜索了源代码树,在/usr/src/sys/amd64/amd64/machdep.c (exec_setregs)中找到了以下代码。

代码语言:javascript
复制
        regs->tf_rsp = ((stack - 8) & ~0xFul) + 8;
        regs->tf_rdi = stack;           /* argv */

这些行看起来表明rsp是对齐的,实际数据在rdi。我修改了代码,得到了预期的结果。

代码语言:javascript
复制
$ cat foo.asm
global _start
_start:
        push    rdi
        mov     rax, 4          ; write
        mov     rdi, 1          ; stdout
        pop     rsi
        mov     rdx, 16         ; 16bytes
        syscall

        mov     rax, 1          ; exit
        syscall
$ nasm -f elf64 foo.asm && ld -o foo foo.o
$ ./foo | hd
00000000  01 00 00 00 00 00 00 00  b0 dc ff ff ff 7f 00 00  |................|
00000010
$ ./foo 2 | hd
00000000  02 00 00 00 00 00 00 00  a8 dc ff ff ff 7f 00 00  |................|
00000010
$ ./foo 2 3 | hd
00000000  03 00 00 00 00 00 00 00  a8 dc ff ff ff 7f 00 00  |................|
00000010
$ ./foo 2 3 4 | hd
00000000  04 00 00 00 00 00 00 00  a8 dc ff ff ff 7f 00 00  |................|
00000010
$ ./foo 2 3 4 5 | hd
00000000  05 00 00 00 00 00 00 00  a8 dc ff ff ff 7f 00 00  |................|
00000010

你能试试rdi吗?

票数 3
EN

Stack Overflow用户

发布于 2011-11-18 12:38:36

对于FreeBSD的标准调用约定,您需要:

代码语言:javascript
复制
movl %edi, %eax

返回状态等于传递的参数数量的最短完整程序为:

代码语言:javascript
复制
movl    %edi, %eax
ret
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8177734

复制
相关文章

相似问题

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