无法在 Assembler NASM 上将数字转换为带有 ASCII 字符的字符串。即 123 -> "1","2","3"。这个数字是无符号的。走这条路
- 首先,我向子例程传递了一个参数——需要处理的数字。
- 然后他每次除以1000000,如果private里面有东西,那么我们把这个bit写入栈中。之前,我把 0 放在堆栈上,并与它进行比较,以防有人输入 00456 而不是 456。如果堆栈中的第一个数字不等于 0,我们将其写入堆栈。
- 我们将除数减少 10。也就是说,每次我们减少排放量,其余部分将在排放量中包含或不存在。例如,205 - 200/100 = 2 余数 5。如果除数(数字校验)为 1,那么我们只需将余数写入堆栈并继续从堆栈中读取。
- 我把所有的东西都出栈了,同时我设置了栈顶不是ebp,也就是每次递增ecx的时候是不是到了末尾,这样我以后就知道字符串的长度了。这种方法使我不必跟踪我在堆栈中放入了多少数字。
- 复制同时改变记录方向的线。由于栈中的123写成123,所以我会从栈中得到321,也就是我先开始读,改加48,从最后写。
我已经审查了所有内容一千次,似乎我已经考虑了所有内容,但是代码不起作用。我不会问这个问题,因为我只是在学习并且不知道如何使用调试器。非常感谢所有回复的人。我不想退出,问题没有解决,就像经常发生的那样。
这是代码本身:
global start_create
section .bss
string resb 7 ;variable parameter
string2 resb 7
section .data
string2_end equ string2
string2_length dd 0
division10 dd 10 ;we will add the counter to get a end of string: how many elements we will have after loop
section .text
start_create: push ebp ;save the ebp
mov ebp, esp ;get the link to esp. ebp stores just lik of its value
mov dword [ebp-4], 0 ;set initial value to check if stack has any value
xor edx, edx ;edx:eax/ecx ; set 0 in edx because edx:eax will be the divisible
mov eax, [ebp+8] ;get the number(parameter) transfered by the calling procedure
mov ecx, 1000000 ;set the digit to divide - divisor - YOU LATER CAN SET ANY NUMBER
division: div ecx ;get the quotient of the number
test eax, eax ;check if the quotient zero
jnz put_not_zero ;if it is not so - push the value in stack - otherwise check the first value in stack
cmp dword [ebp-4], 0 ;check if initial value on stack is 0, it means we will not put the number in stack
jnz push_in_stack ;if first argument is not 0, push 0 in stack 0!+0 12...+0
jmp next_digit ;if the first argument is 0
put_not_zero: cmp dword [ebp-4], 0 ;
jnz push_in_stack
mov [ebp-4], eax ;clear the first initial value with normal value
push_in_stack: push eax ;save the digit in stack
next_digit: cmp ecx, 1 ; check if divisor is 10 to finish the loop
jne continue_division
push edx ;if divisor is 10 we will not continue loop. We will put the remainder in stack
jmp read_to_create_string
continue_division:
mov ebx, edx ;move the remainder to ebx to save it
mov eax, ecx ;decrement divisor by 10 lower
xor edx, edx ;zero the value of the edx, because edx is part of division operation
div dword [division10]
mov ecx, eax ;set the new digit divisor
mov eax, ebx ;get the remainder for division operation
jmp division
read_to_create_string:
mov ecx, 0
read_from_stack:
cmp esp, ebp ;check if we go to a start of the adress of procedure [return adress - 4] = ebp, or we do not have string
je create_ascii_symbols
pop edx
mov [string + ecx], dl ;write the in string
inc ecx ;increment ecx to write next number from stack to memory
jmp read_from_stack
create_ascii_symbols:
mov [string2_length], ecx ; change value to strore length of taken string to display it later
add [string2_end], cl ;string2_end == string2 we add cl instead because we add byte to byte, and in ecx we have not so big number
mov esi, string
mov edi, string2_end
add48_to_ASCII: cld ;we do not set value in ecx - counter because we have it afer previously
lodsb ;load number to create ascii symbol
add eax, 48 ;
std ;change direction to write not 3,2,1 to 1,2,3 . To write from the end
stosb ;
loop add48_to_ASCII ;repeat the action several times pointed in ecx - length of the string
;in string we have string of numbers in ASCII
display: mov eax, 4
mov ebx, 1
mov ecx, string
mov edx, string2_length
int 80h
mov esp, ebp
pop ebp
ret
您正在描述某种超现实主义算法。还是很简单:
30h
字符串末尾的余数(将数字转换为字符)输入号码
eax