如何用sys_write正确替换printf?

时间:2017-01-20 01:17:35

标签: linux assembly 32-bit intel-syntax

我正在发布关于同一节目的新帖子 - 对不起,但我认为我的问题与前一个问题有很大不同。我的程序在开始时获得2个参数 - 重复次数和字符串。重复次数决定了字符串中最后一个字的打印次数。例如:

./a.out 3 "ab cd"

显示在输出

cdcdcd

我已经(使用Stack用户帮助:-))使用call printf编写了一个工作程序。它仅适用于0-9个重复次数,但它并不像主要的那样重要 - 我的问题是如何用sys_write调用替换这个“call printf”。

我得到的信息是我必须使用

编译它
  

-nostdlib

选项但是我的代码不正确无关紧要。我尽我所能,我也在这里找到了一些关于可能的方法的信息,但我无法使其正常工作。

打印新行很好但我不知道如何处理与sys_write连接的参数#2中的字符串。如果有经验的人找到一些时间并指出我需要在代码中更改的内容,那将会很棒。花了一些时间来通过“call printf”版本,但后来我能够进行实验,现在我完全迷失了。这是:

.intel_syntax noprefix

.globl _start
.text

_start:
    push ebp
    mov ebp, esp
    mov ecx, [ebp + 4] # arg1 int ECX 
    mov ebx, [ebp + 8] # arg2 string EBX
    xor eax, eax

# ARG1 - FROM STRING TO INT
atoi:
    movzx edx, byte ptr [ecx]
    cmp edx, '0'
    jb programend
    sub edx, '0'
    mov ecx, edx


## =========================== FUNCTION =========================== ##  

# SEARCH FOR END OF STRING
findend:
    mov dl, byte ptr [ebx + eax] # move through next letters
    cmp dl, 0 
    jz findword
    inc eax
    jmp findend

# SEARCH FOR LAST SPACE
findword:
    dec eax
    mov dl, byte ptr [ebx + eax]
    cmp dl, ' '
    jz foundwordstart
    jmp findword

# REMEMBER SPACE POSITION, CHECK COUNTER >0
foundwordstart:
    push eax # remember space position
    cmp ecx, 0 # check if counter > 0
    jz theend
    jmp foundword

 # PRINT LAST WORD
foundword:
    inc eax 
    mov dl, byte ptr [ebx + eax]
    cmp dl, 0
    jz checkcount
    push ecx
    push eax # save current position in word
    push edx
    push ebx

    lea ecx, [ebx+eax] # char * to string
    mov eax, 4 # sys_write
    mov edx, 1; # how many chars will be printed
    mov ebx, 1 # stdout
    int 0x80

    pop ebx
    pop edx
    pop eax
    pop ecx
    jmp foundword

# decrease counter and restore beginning of last word
checkcount:
    dec ecx # count = count-1 
    pop eax # restore beginning of last word
    jmp foundwordstart

theend:
    pop eax # pop the space position from stack
    jmp programend

# END OF PROGRAM
programend:
    pop ebp

    # new line
    mov eax,4
    mov ebx,1
    mov ecx,offset msgn
    mov edx,1
    int 0x80

    # return 0
    mov eax, 1
    mov ebx, 0
    int 0x80


.data
 msgn:   .ascii "\n"

我可以用以下方式运行它,这对我来说也很奇怪:

    mov ecx, [ebp + 12]
    mov ecx, [ecx + 8]

    add ecx, eax # char * to string
    mov eax, 4 # sys_write
    mov edx, 1; # how many chars will be printed
    mov ebx, 1 # stdout
    int 0x80

并且效果很好 - 但是只有当我不使用-nostdlib时(当然我必须将_start更改为main)...

0 个答案:

没有答案