0

因此,我将通过说我是 NASM 的新手并且正在阅读http://www.drpaulcarter.com/pcasm/组装教程来限定这一点。

我正在使用 32 位 80x86 作为我的指令集在 Linux(Ubuntu)中编译(我认为......)。

我的程序的目的是从读入的字符串中删除任何不必要的空格。因此,字符串开头的所有空格,以及单词之间的任何双倍或更大的空格。

我的程序几乎完成了一个困扰我的未记录功能。如果我有一个带有两个尾随空格的单词和一个带有一个尾随空格的单词,我的程序将吃掉第二个单词的单个尾随空格。但是这个错误通常不会发生,只有两个空格一个空格排列的第一个实例。

这是我的制作文件:

mstrebl  : asm_io.inc  asm_io.o driver.o mstrebl.o
    gcc -o mstrebl -m32 asm_io.o driver.o mstrebl.o

driver.o : driver.c
    gcc -c driver.c -m32

mstrebl.o: mstrebl.asm
    nasm -f elf32 mstrebl.asm

这是在所有教程程序中调用 ASM_MAIN 的 C 程序

int main()
{
  int ret_status;
  ret_status = asm_main();
  return ret_status;
}

这是我的 ASM 文件。

%include "asm_io.inc"

LF  equ 0Ah

segment .data

name_prompt    DB  'Please enter a string to be trimmed: ',0
out_msg        DB  'The trimmed string is: ',0

segment .bss

in_name    resb  80

segment .text
        global  asm_main
asm_main:
        enter   0,0            ; setup routine
        pusha
restart:

    mov  eax, name_prompt  ; print prompt
    call print_string
    mov  ebx, in_name
                       ;for counting the number of digits
rd_loop:

    call read_char         ; read in the string
    mov  [ebx], al
        inc  ebx
    cmp  al, LF
        jne  rd_loop

    dec  ebx               ; put in null terminator
    mov  byte [ebx], 0
        call print_nl          ; print output msg
        mov  eax, out_msg
    call print_string
        mov  ebx, in_name      ; EBX := address of in_name   

    push in_name
    call strebl             ;this pushes the string onto EAX, destroying old data.

    call print_string 
    add esp, 4

Finished:

        call print_nl
        call print_nl

        popa
        mov     eax, 0         ; return back to C
        leave                     
        ret

; subprogram get_int
; Parameters (in order pushed on stack)
;
;Address of the first character in a string (at [ebp + 8])
; Notes:
; There are no data shifts on the stack, only for the address
; of the array, as such, esp is not changed or shifted.
;
; Note, this destroys the contents of EAX.
; Note, this destroys the contents of CL.


;SUDO CODE!
;j = first address of the string
;if(*char == '\0')
;   return *char
;while((*char + i) == ' ')
;   i += 1 
; 
;
;while((*char + i != ' '))
;{
;   if((*char + i) == '\0')
;       return *char
;
;   (*char + j) = (*char + i)
;   j += 1;
;}
;
;jump to original while

segment .data

temp   db 0

segment .text
 strebl:
    push EBP
    mov  EBP, ESP
    mov  EAX, [EBP + 8] ; I
    mov  EBP, [EAX]     ; J

 First_while:

    cmp byte [EAX], 0
    je  End_strebl
    cmp byte[EAX], ' ' ;or 32 if i need to change it
    jne Second_While

    inc EAX ; i
    jmp First_while

 Second_While:

    cmp byte [EAX], 0
    je  End_strebl    

    cmp byte[EAX], ' '
    je  Second_While_helper

    ;*EBX = *EAX
    mov ECX, [EAX]
    mov [EBX], ECX

    inc EAX ; increment I and J at the same time 
    inc EBX

    jmp Second_While

Second_While_helper:

    inc EAX
    inc EBX

helper_loop:

    cmp byte[EAX], ' '
    jne Second_While

    inc EAX

    jmp helper_loop

End_strebl:
    cmp EAX, EBX
    jz  done_strebl
    mov byte[EBX], ' '

done_strebl:

    mov EAX, [ESP + 8]
    pop EBP
    ret
4

1 回答 1

0

500- 内部服务器错误在上面的评论中指出了我的错误。

于 2012-08-10T00:53:53.457 回答