したがって、私は NASM の初心者であり、http://www.drpaulcarter.com/pcasm/アセンブリ チュートリアルを読んでいると言って、これを限定します。
命令セットとして 32 ビット 80x86 を使用して Linux (Ubuntu) でコンパイルしています (と思います...)。
私のプログラムの目的は、読み込まれた文字列から不要なスペースを取り除くことです。そのため、文字列の先頭にあるすべてのスペース、および単語間の 2 つ以上のスペース。
私のプログラムは、私を悩ませている 1 つの文書化されていない機能でほぼ完成しています。末尾に 2 つのスペースがある単語と、末尾に 1 つのスペースがある単語がある場合、プログラムは 2 番目の単語の末尾の 1 つのスペースを消費します。しかし、このバグは通常は発生せず、2 スペース 1 スペースが並んだ最初のインスタンスのみです。
これが私のメイクファイルです:
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