簡體   English   中英

在沒有printf的NASM中打印ARGC

[英]Print ARGC in NASM without printf

有沒有好的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()

當我們“彈出”堆棧時,我們在技術上應該獲得全部參數,不是嗎? 哦,順便說一句,我編譯:

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

不確定這是否相關。 如果我需要提供更多信息或格式化我的代碼以便於閱讀,請告訴我。

至少有2個問題。

  1. 您需要將指針傳遞給要打印的內容。
  2. 您可能想要轉換為文本。

這樣的事情應該有效:

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

每個人的評論都非常有幫助! 我很榮幸你們都投入並幫助過! 我用過@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!

然后通過 ESP 指向的值 (即ARGC) 添加一個'0'字符 ,通過用方括號取消引用 ,將其轉換為字符串,如[ESP]那樣,

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

再次感謝大家的幫助! <3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM