[英]Print ARGC in NASM without printf
Any good NASM/Intel Assembly programmers out there? 有没有好的NASM /英特尔组装程序员? If so, I have a question for you!
如果是这样,我有一个问题给你!
Every tutorial I can find online, shows the usage of "printf" for printing the actual value of ARGC to the screen (fd:/dev/stdout). 我可以在网上找到的每个教程都显示了“printf”的用法,用于将ARGC的实际值打印到屏幕上(fd:/ dev / stdout)。 Is it not possible to simply print it with sys_write() for example:
是不是可以简单地用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
When I run this, I get no output at all. 当我运行它时,我根本没有输出。 I have tried copying ESP into EBP and tried using byte[EBP+4], (i was told the brackets de-reference the memory address).
我曾尝试将ESP复制到EBP并尝试使用byte [EBP + 4],(我被告知括号取消引用内存地址)。
I can confirm that the value when compared to a constant, works. 我可以确认,当与常数相比时,该值有效。 For instance, this code works:
例如,此代码有效:
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()
When we "pop" the stack, we technically should get the full number of arguments, no? 当我们“弹出”堆栈时,我们在技术上应该获得全部参数,不是吗? Oh, btw, I compile with:
哦,顺便说一句,我编译:
nasm -f elf test.asm -o test.o
ld -o test test.o
not sure if that is relevant. 不确定这是否相关。 Let me know if i need to provide more information, or format my code for readability.
如果我需要提供更多信息或格式化我的代码以便于阅读,请告诉我。
At least 2 problems. 至少有2个问题。
Something like this should work: 这样的事情应该有效:
SEGMENT .text ; sauce
global _start
_start:
mov ecx, esp ; pointer to ARGC on stack
add byte [esp], '0' ; convert to text assuming single digit
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
Everyone's comments where very helpful! 每个人的评论都非常有帮助! I am honored that you all pitched in and helped!
我很荣幸你们都投入并帮助过! I have used @Jester's code,
我用过@Jester的代码,
SEGMENT .text ; sauce
global _start
_start:
mov ecx, esp ; pointer to ARGC on stack
add byte [esp], '0' ; convert to text assuming single digit
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
Which works perfectly when compiled, linked and loaded. 这在编译,链接和加载时非常有效。 The sys_write() function requires a pointer, such like in the common "Hello World" example, the symbol "msg" is a pointer as seen in the code below.
sys_write()函数需要一个指针,就像在常见的“Hello World”示例中一样,符号“msg”是一个指针,如下面的代码所示。
SECTION .data ; initialized data
msg: db "Hello World!",0xa
SECTION .text ; workflow
global _start
_start:
mov EAX, 4
mov EBX, 1
mov ECX, msg ; a pointer!
So first, we move the stack pointer into the counter register, ECX , with the code, 首先,我们使用代码将堆栈指针移动到计数器寄存器ECX中 ,
mov ecx, esp ; ecx now contains a pointer!
and then convert it to a string by adding a '0' char to the value pointed to by ESP (which is ARGC), by de-referencing it with square brackets, as [ESP] like so, 然后通过向 ESP 指向的值 (即ARGC) 添加一个'0'字符 ,通过用方括号取消引用 ,将其转换为字符串,如[ESP]那样,
add byte[esp], '0' ; update the value stored at "esp"
Again, thank you all for the great help! 再次感谢大家的帮助! <3
<3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.