在没有printf的情况下在NASM中打印ARGC

时间:2015-10-26 18:15:17

标签: linux assembly x86 nasm

任何优秀的NASM /英特尔组装程序员都在那里?如果是这样,我有一个问题给你!

我可以在网上找到的每个教程都显示" 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()

当我们" pop"堆栈,我们技术上应该得到全部的参数,不是吗?哦,顺便说一句,我编译:

nasm -f elf test.asm -o test.o
ld -o test test.o

不确定这是否相关。如果我需要提供更多信息或格式化我的代码以便于阅读,请告诉我。

2 个答案:

答案 0 :(得分:3)

至少有2个问题。

  1. 您需要将指针传递给您要打印的内容。
  2. 您可能想要转换为文字。
  3. 这样的事情应该有效:

    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
    

答案 1 :(得分:1)

每个人的评论都非常有帮助!我很荣幸你们都投入并帮助过!我使用过@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

编译,链接和加载时效果很好。 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!

首先,我们将堆栈指针移动到计数器寄存器 ECX ,并带有代码,

mov ecx, esp ; ecx now contains a pointer!

然后通过将“0”字符添加到ESP指向的值(即ARGC),通过取消引用将其转换为字符串方括号,如[ESP]那样,

add byte[esp], '0' ; update the value stored at "esp"

再次感谢大家的帮助! < 3