反转 ASM 中字符串的顺序 (NASM)
Reversing order of a string in ASM (NASM)
在颠倒字符串字符的顺序时遇到问题,它适用于整数而不是字符串。它正在输出包括字符串在内的所有内容,直到我 "reverse" 它。然后它只是输出一个空行......而不是以相反的顺序输出字符串。我觉得我的字符串数组出了问题。任何帮助将不胜感激...
更新:我让它工作但不得不手动从 array2Len 中减去 1(当然是将它放在 eax 中,等等)。这没有意义,为什么 array2Len 差了一个?
我用过:
array2Len: equ $-array2 in the .data section
但它说它是 14 长度(当我在测试时输出它时),而实际上它是 13...你会在底部看到我手动使其工作,(它目前已被注释掉)。有人知道为什么 Equ $-array2 会差一个吗?
extern printf ; the C function, to be called
SECTION .data ; Data section, initialized variables
unitSize: dd 4 ; size of unit (for testing starts at 4)
array: dd 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ; this is a test array for testing purposes
array2: db "Hello, world!", 0 ; second array test for if it is a string
array2Len: equ $-array2
arrayLen: dd 10 ; length of array
;ainput: db "%d", 0 ; input format
asoutput: db "%s", 0
aoutput: db "%d ", 0 ; output format
newline: db "", 10, 0 ; format for a new line
SECTION .bss ; BSS, uninitialized variables
SECTION .text ; Code section.
global main ; the standard gcc entry point
reverse:
;lets test
push ebp
mov ebp, esp
mov ebx, [ebp+8]
mov eax, [ebp+12]
mov ecx, [ebp+16]
sub esp, 8
mov dword [ebp-4], eax ; size of units. i.e. is it 4 bytes? 1 byte between array values (such as a string), or 4 bytes (like an int, etc.)
mov dword [ebp-8], ecx ; size of array (including if it is strings)
push ebx
mov esi, ebx ; array index that starts at beginning of array
mov edi, ebx ; array index that will start at end of array
; calculate the end of the array by multiplying the (length of array - 1) by unit size
mov eax, [ebp-8]
sub eax, 1
mov ebx, [ebp-4] ; size of units
mul ebx
add edi, eax ; array index now starts at the end of the array
; going to go through until we get to the middle
mov ebx, 2
mov eax, [ebp-8]
cdq
div ebx
mov ecx, eax ; number of times to run loop set up
;mov ecx, 8
;jmp .stringloop
mov eax, 4
cmp [ebp-4], eax
jne .stringloop
.loop: ; loop through indexes of array and reverse the array
push dword [esi]
push dword [edi]
pop dword [esi]
pop dword [edi]
add esi, [ebp-4]
sub edi, [ebp-4]
loop .loop
jmp .end
.stringloop:
mov al, [esi]
mov bl, [edi]
mov [esi], bl
mov [edi], al
;inc esi
;dec edi
add esi, 1;[ebp-4]
sub edi, 1;[ebp-4]
loop .stringloop
.end:
pop ebx ; get back our address of the array
mov esp, ebp ; takedown stack frame
pop ebp ; same as "leave" op
mov eax, ebx ; put the address of the array in eax to get it back
ret ; return :)
main: ; the program label for the entry point
push ebp ; set up stack frame
mov ebp,esp
;jmp .stringcheck
mov ecx, [arrayLen] ; loop counter set up
mov esi, 0 ; counter to increment set up for looping through array
.loop:
push ecx ; make sure to put ecx (counter) on stack so we don't lose it when calling printf)
push dword [array + esi] ; put the value of the array at this (esi) index on the stack to be used by printf
push dword aoutput ; put the array output format on the stack for printf to use
call printf ; call the printf command
add esp, 8 ; add 4 bytes * 2
pop ecx ; get ecx back
add esi, 4
loop .loop
push dword newline
call printf
add esp, 4
mov eax, [arrayLen]
push eax
mov eax, array
mov ecx, [unitSize]
push ecx
push eax
call reverse
mov ebx, eax ; got address of array back from reverse function
mov ecx, [arrayLen] ; counter for # of times loop to run set up
mov esi, 0 ; index counter set up
.loop2:
push ebx
push ecx ; make sure to put ecx (counter) on stack so we don't lose it when calling printf)
push dword [ebx + esi] ; put the value of the array at this (esi) index on the stack to be used by printf
push dword aoutput ; put the array output format on the stack for printf to use
call printf ; call the printf command
add esp, 8 ; add 4 bytes * 2
pop ecx ; get ecx back
pop ebx
add esi, 4
loop .loop2
push dword newline
call printf
add esp, 4
.stringcheck:
push dword array2
push dword asoutput ; string output format
call printf ; call the printf command
add esp, 8 ; add 4 bytes * 2
push dword newline
call printf
add esp, 4
;mov eax, array2Len
;sub eax, 1
;mov ebx, eax
mov ebx, array2Len
push ebx
mov eax, array2
mov ecx, 1
push ecx
push eax
call reverse
mov ebx, eax
push ebx
push dword asoutput
call printf
add esp, 8
push dword newline
call printf
add esp, 4
mov esp, ebp ; takedown stack frame
pop ebp ; same as "leave" op
mov eax,0 ; normal, no error, return value
ret ; return
该字符串被定义为 13 个字节,但它明确地 "null" 终止 - 末尾的零字节用作指示字符串结尾的标记,请参阅 here。
你是这样定义的
array2: db "Hello, world!", 0 ; second array test for if it is a string
array2Len: equ $-array2
db
指令表示您正在定义字节,13 个字节作为字符串文字给出,空字节在逗号后明确给出。当您计算 array2Len 时,您是在告诉汇编程序计算表达式 $-array2
,符号 $
是当前偏移量,它是字符串文字末尾后的偏移量(因为空字节)。
在颠倒字符串字符的顺序时遇到问题,它适用于整数而不是字符串。它正在输出包括字符串在内的所有内容,直到我 "reverse" 它。然后它只是输出一个空行......而不是以相反的顺序输出字符串。我觉得我的字符串数组出了问题。任何帮助将不胜感激...
更新:我让它工作但不得不手动从 array2Len 中减去 1(当然是将它放在 eax 中,等等)。这没有意义,为什么 array2Len 差了一个?
我用过:
array2Len: equ $-array2 in the .data section
但它说它是 14 长度(当我在测试时输出它时),而实际上它是 13...你会在底部看到我手动使其工作,(它目前已被注释掉)。有人知道为什么 Equ $-array2 会差一个吗?
extern printf ; the C function, to be called
SECTION .data ; Data section, initialized variables
unitSize: dd 4 ; size of unit (for testing starts at 4)
array: dd 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ; this is a test array for testing purposes
array2: db "Hello, world!", 0 ; second array test for if it is a string
array2Len: equ $-array2
arrayLen: dd 10 ; length of array
;ainput: db "%d", 0 ; input format
asoutput: db "%s", 0
aoutput: db "%d ", 0 ; output format
newline: db "", 10, 0 ; format for a new line
SECTION .bss ; BSS, uninitialized variables
SECTION .text ; Code section.
global main ; the standard gcc entry point
reverse:
;lets test
push ebp
mov ebp, esp
mov ebx, [ebp+8]
mov eax, [ebp+12]
mov ecx, [ebp+16]
sub esp, 8
mov dword [ebp-4], eax ; size of units. i.e. is it 4 bytes? 1 byte between array values (such as a string), or 4 bytes (like an int, etc.)
mov dword [ebp-8], ecx ; size of array (including if it is strings)
push ebx
mov esi, ebx ; array index that starts at beginning of array
mov edi, ebx ; array index that will start at end of array
; calculate the end of the array by multiplying the (length of array - 1) by unit size
mov eax, [ebp-8]
sub eax, 1
mov ebx, [ebp-4] ; size of units
mul ebx
add edi, eax ; array index now starts at the end of the array
; going to go through until we get to the middle
mov ebx, 2
mov eax, [ebp-8]
cdq
div ebx
mov ecx, eax ; number of times to run loop set up
;mov ecx, 8
;jmp .stringloop
mov eax, 4
cmp [ebp-4], eax
jne .stringloop
.loop: ; loop through indexes of array and reverse the array
push dword [esi]
push dword [edi]
pop dword [esi]
pop dword [edi]
add esi, [ebp-4]
sub edi, [ebp-4]
loop .loop
jmp .end
.stringloop:
mov al, [esi]
mov bl, [edi]
mov [esi], bl
mov [edi], al
;inc esi
;dec edi
add esi, 1;[ebp-4]
sub edi, 1;[ebp-4]
loop .stringloop
.end:
pop ebx ; get back our address of the array
mov esp, ebp ; takedown stack frame
pop ebp ; same as "leave" op
mov eax, ebx ; put the address of the array in eax to get it back
ret ; return :)
main: ; the program label for the entry point
push ebp ; set up stack frame
mov ebp,esp
;jmp .stringcheck
mov ecx, [arrayLen] ; loop counter set up
mov esi, 0 ; counter to increment set up for looping through array
.loop:
push ecx ; make sure to put ecx (counter) on stack so we don't lose it when calling printf)
push dword [array + esi] ; put the value of the array at this (esi) index on the stack to be used by printf
push dword aoutput ; put the array output format on the stack for printf to use
call printf ; call the printf command
add esp, 8 ; add 4 bytes * 2
pop ecx ; get ecx back
add esi, 4
loop .loop
push dword newline
call printf
add esp, 4
mov eax, [arrayLen]
push eax
mov eax, array
mov ecx, [unitSize]
push ecx
push eax
call reverse
mov ebx, eax ; got address of array back from reverse function
mov ecx, [arrayLen] ; counter for # of times loop to run set up
mov esi, 0 ; index counter set up
.loop2:
push ebx
push ecx ; make sure to put ecx (counter) on stack so we don't lose it when calling printf)
push dword [ebx + esi] ; put the value of the array at this (esi) index on the stack to be used by printf
push dword aoutput ; put the array output format on the stack for printf to use
call printf ; call the printf command
add esp, 8 ; add 4 bytes * 2
pop ecx ; get ecx back
pop ebx
add esi, 4
loop .loop2
push dword newline
call printf
add esp, 4
.stringcheck:
push dword array2
push dword asoutput ; string output format
call printf ; call the printf command
add esp, 8 ; add 4 bytes * 2
push dword newline
call printf
add esp, 4
;mov eax, array2Len
;sub eax, 1
;mov ebx, eax
mov ebx, array2Len
push ebx
mov eax, array2
mov ecx, 1
push ecx
push eax
call reverse
mov ebx, eax
push ebx
push dword asoutput
call printf
add esp, 8
push dword newline
call printf
add esp, 4
mov esp, ebp ; takedown stack frame
pop ebp ; same as "leave" op
mov eax,0 ; normal, no error, return value
ret ; return
该字符串被定义为 13 个字节,但它明确地 "null" 终止 - 末尾的零字节用作指示字符串结尾的标记,请参阅 here。
你是这样定义的
array2: db "Hello, world!", 0 ; second array test for if it is a string
array2Len: equ $-array2
db
指令表示您正在定义字节,13 个字节作为字符串文字给出,空字节在逗号后明确给出。当您计算 array2Len 时,您是在告诉汇编程序计算表达式 $-array2
,符号 $
是当前偏移量,它是字符串文字末尾后的偏移量(因为空字节)。