Assembly 以十进制打印出寄存器,不带printf
我正试图从屏幕上的寄存器EDX打印出值。 程序应找到最大偏执深度,例如((x))EDX=2 我不能用stdlib。 我的程序使用stdlibAssembly 以十进制打印出寄存器,不带printf,assembly,x86,printf,decimal,Assembly,X86,Printf,Decimal,我正试图从屏幕上的寄存器EDX打印出值。 程序应找到最大偏执深度,例如((x))EDX=2 我不能用stdlib。 我的程序使用stdlib .intel_syntax noprefix .globl main .text main: pop eax #return address pop eax #return argc pop eax #return argv mov eax,[eax+4] #argv[1] sub esp,12 #return stack to the righ
.intel_syntax noprefix
.globl main
.text
main:
pop eax #return address
pop eax #return argc
pop eax #return argv
mov eax,[eax+4] #argv[1]
sub esp,12 #return stack to the right position
lea ebx,[eax]
xor eax,eax
xor ecx,ecx
xor edx,edx
loop:
mov al,[ebx]
or al,al
jz print
cmp al,'('
je increase
cmp al,')'
je decrease
inc ebx
jmp loop
increase:
inc ecx
cmp edx,ecx
js changeMax
inc ebx
jmp loop
changeMax:
mov edx,ecx
inc ebx
jmp loop
decrease:
dec ecx
inc ebx
jmp loop
print:
push edx
mov edx, offset mesg
push edx
call printf
add esp,8
ret
mov edx,0
ret
data:
mesg: .asciz "%d\n"
我读到,我需要使用模,并将余数推入堆栈。
这是另一种方法吗(proffesor说了一些关于移动十六进制值的事情)
更新
这应该行得通,但我犯了个错误
.intel_syntax noprefix
.text
.globl _start
_start:
op eax #return address
pop eax #return argc
pop eax #return argv
mov eax,[eax+4] #argv[1]
sub esp,12 #return stack to right position
lea ebx,[eax]
xor eax,eax
xor ecx,ecx
xor edx,edx
loop:
mov al,[ebx]
or al,al
jz result
cmp al,'('
je increase
cmp al,')'
je decrease
inc ebx
jmp loop
increase:
inc ecx
cmp edx,ecx
js changeMax
inc ebx
jmp loop
changeMax:
mov edx,ecx
inc ebx
jmp loop
decrease:
dec ecx
inc ebx
jmp loop
result:
mov eax, edx # moving result into eax, because of div operation
conv:
mov ecx, 10
xor ebx, ebx
divide:
xor edx, edx
div ecx
push edx
inc ebx
test eax, eax
jnz divide
next_digit:
pop eax
add eax, '0'
mov [sum], eax
dec ebx
cmp ebx, 0
je final
pop eax
add eax, '0'
mov [sum+1], eax
dec ebx
cmp ebx, 0
je final
pop eax
add eax, '0'
mov [sum+2], eax
dec ebx
cmp ebx, 0
je final
final:
mov edx, 3 #length of string
mov ecx, offset sum
mov ebx, 1
mov eax, 4
int 0x80
mov edx, 1
mov ecx, offset msg
mov ebx, 1
mov eax, 4
int 0x80
mov eax, 1
int 0x80
.data
msg: .ascii "\n"
sum: .byte 0, 0, 0, 0
好的,这是我的解决方案
.intel_syntax noprefix
.globl _start
.text
_start:
mov eax, [esp+8] #argv[0] to eax
lea ebx,[eax]
xor eax,eax
xor ecx,ecx
xor edx,edx
loop:
mov al,byte ptr [ebx]
or al,al
jz result #end of the argument
cmp al,'('
je increase
cmp al,')'
je decrease
inc ebx
jmp loop
increase:
inc ecx
cmp edx,ecx
js changeMax
inc ebx
jmp loop
changeMax:
mov edx,ecx
inc ebx
jmp loop
decrease:
dec ecx
inc ebx
jmp loop
result:
mov eax, edx
base:
mov ecx,10
xor ebx, ebx
divide:
xor edx, edx
div ecx
push edx
inc ebx
test eax, eax
jnz divide
to_ASCII:
pop eax
add eax, '0'
mov [sum], eax
dec ebx
cmp ebx, 0
je print
pop eax
add eax, '0'
mov [sum+1], eax
dec ebx
cmp ebx, 0
je print
pop eax
add eax, '0'
mov [sum+2], eax
dec ebx
print:
mov eax, 4
mov ebx, 1
mov ecx, offset sum
mov edx, 3 #
int 0x80
mov eax,4
mov ebx,1
mov ecx, offset msg
mov edx,1
int 0x80
mov eax,1
mov ebx,0
int 0x80
.data
msg: .asciz "\n"
sum: .byte 0,0,0,0
如果你想用十六进制打印,你可以使用移位。无论如何,有很多关于十进制和十六进制的例子,只要做一些搜索就可以了。分段错误通常意味着访问无效地址,通常一个设置良好的调试器只会在导致冲突的指令上停止,所以你可以从实际寄存器值猜出发生了什么(或者在单步模式下重新运行,如果您无法从最终崩溃状态猜到它)。