【发布时间】:2016-01-25 23:14:58
【问题描述】:
那里有好的 NASM/Intel 汇编程序员吗?如果是这样,我有一个问题要问你!
我可以在网上找到的每个教程都显示了“printf”的用法,用于将 ARGC 的实际值打印到屏幕上(fd:/dev/stdout)。是不是可以简单地用 sys_write() 打印它,例如:
SEGMENT .data ; nothing here
SEGMENT .text ; sauce
global _start
_start:
pop ECX ; get ARGC value
mov EAX, 4 ; sys_write()
mov EBX, 1 ; /dev/stdout
mov EDX, 1 ; a single byte
int 0x80
mov EAX, 1 ; sys_exit()
mov EBX, 0 ; return 0
int 0x80
SEGMENT .bss ; nothing here
当我运行它时,我根本没有得到任何输出。我尝试将 ESP 复制到 EBP 并尝试使用 byte[EBP+4],(我被告知括号取消引用内存地址)。
我可以确认,与常数相比,该值有效。例如, 此代码有效:
pop ebp ; put the first argument on the stack
mov ebp, esp ; make a copy
cmp byte[ebp+4],0x5 ; does it equal 5?
je _good ; goto _good, &good, good()
jne _bad ; goto _bad, &bad, bad()
当我们“弹出”堆栈时,从技术上讲,我们应该得到完整数量的参数,不是吗?哦,顺便说一句,我编译:
nasm -f elf test.asm -o test.o
ld -o test test.o
不确定这是否相关。如果我需要提供更多信息或格式化我的代码以提高可读性,请告诉我。
【问题讨论】:
-
sys_write接受一个指向字符串的指针(以及数组中的字符数)。您需要将您的数字 argc 转换为字符串,然后将指向该字符串的指针传递给sys_write系统调用。 -
用 C 语言编写一些东西并查看编译器输出通常很有用。特别是。在您学习时,它会发现这样的错误(
write(2)需要值与指针)。此外,使用pop获取参数很奇怪。它在_start中工作,但在任何其他上下文中,堆栈底部将保存您的返回地址。另外,pop ebp/mov ebp, esp很奇怪。如果您要在下一条指令中覆盖 ebp,为什么不直接使用add esp, 4?如果您还没有看到,请查看agner.org/optimize 和stackoverflow.com/tags/x86/info 上的其他链接 -
@kp101st:你不应该在标题中加上“SOLVED”。如果有一个答案可以解决您的问题,请将其标记为已接受(如果您愿意,也可以投票)。
-
@Michael 谢谢!我是新手! :S