【发布时间】:2017-01-18 00:01:32
【问题描述】:
我正在尝试从屏幕上的寄存器 EDX 中打印出值。 程序应该找到括号的最大深度,例如 ((x)) EDX = 2
而且我不能使用标准库。 我的程序使用标准库
.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"
我读到,我需要使用模数,并将余数压入堆栈。 是否有另一种方式来做到这一点(教授说了一些关于转移十六进制值的事情)
更新
这应该可以,但是我遇到了分段错误
.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
【问题讨论】:
-
如果您想以十六进制打印,您可以使用班次。无论如何,十进制和十六进制的大量示例,只需搜索一下即可。
-
分段错误通常意味着对无效地址的访问,并且通常设置良好的调试器只会停止导致违规的指令,因此您可以从实际寄存器值中猜测发生了什么(或重新运行它)单步模式,如果您无法从最终崩溃状态中猜到它)。
标签: assembly x86 printf decimal