帮助编写汇编代码(将字符串转换为 int)
我正在尝试用汇编语言编写这个程序。 它应该只是将字符串转换为十进制
int main (int argc, char **argv)
{
int result = 0;
char *c = argv[1];
while(*c != 0)
{
result *= 10;
result += (*c - 48);
c++;
}
return result;
}
,但不从堆栈中获取 argv...所以我在 asm 中编写了一些代码,我认为应该这样做,但它不起作用。
谁能指出我做错了什么? 我对代码进行了评论,以便您知道我认为发生了什么,请纠正我。
section .bss
buf resb 8 ; define an array of 8 uninitialised bytes
section .text
global _start
_start:
mov rax, 3 ; system call number (sys_read)
xor rbx, rbx ; file descriptor 0 (stdin)
mov rcx, buf ; buffer to store data
mov rdx, 8 ; Lenght of buffer
int 0x80
xor rax,rax ; rax = 0
mov rbx, buf ; rbx = &buf
xor rcx, rcx
StrToDec:
mov cl, [rbx] ; cl = *rbx
cmp rcx, 0 ; check for nul THIS IS WRONG
cmp rcx, 10 ; we have to check for NL ascii code
je end ; if rcx == 0 goto end
imul rax, 10 ; rax *= 10
sub rcx, 48 ; rcx -= 48 (48 is acii for '0')
add rax, rcx ; rax += rcx
inc rbx ; rbx++
jmp StrToDec
end:
mov rbx, rax ; rbx = rax
mov rax, 1 ; rax = 1
int 0x80
例如,当我运行这个程序并输入 100 时 然后输入 echo $?到终端它应该打印 100
谢谢。
I'm trying to make this program in assembly.
It should just convert a string to a decimal
int main (int argc, char **argv)
{
int result = 0;
char *c = argv[1];
while(*c != 0)
{
result *= 10;
result += (*c - 48);
c++;
}
return result;
}
but without getting argv from the stack... so I wrote a little code in asm that I think should do this but it does not work.
Can anyone point me to what I'm doing wrong?
I commented the code so you will know what I think is going on, please correct me with anything.
section .bss
buf resb 8 ; define an array of 8 uninitialised bytes
section .text
global _start
_start:
mov rax, 3 ; system call number (sys_read)
xor rbx, rbx ; file descriptor 0 (stdin)
mov rcx, buf ; buffer to store data
mov rdx, 8 ; Lenght of buffer
int 0x80
xor rax,rax ; rax = 0
mov rbx, buf ; rbx = &buf
xor rcx, rcx
StrToDec:
mov cl, [rbx] ; cl = *rbx
cmp rcx, 0 ; check for nul THIS IS WRONG
cmp rcx, 10 ; we have to check for NL ascii code
je end ; if rcx == 0 goto end
imul rax, 10 ; rax *= 10
sub rcx, 48 ; rcx -= 48 (48 is acii for '0')
add rax, rcx ; rax += rcx
inc rbx ; rbx++
jmp StrToDec
end:
mov rbx, rax ; rbx = rax
mov rax, 1 ; rax = 1
int 0x80
When i run this program and type 100 for example
and then type echo $? to the terminal it should print 100
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是错误的,它从缓冲区加载八个字节。您只想加载 1. 使用
mov cl,[rbx]
或movzx ecx, byte [rbx]
That's wrong, it loads eight bytes from the buffer. You want to load only 1. Use
mov cl,[rbx]
ormovzx ecx, byte [rbx]
修复:
我发现程序出了什么问题=D
首先你需要检查值 10 所以
是错误的,因为我们正在寻找新行 ascii 代码而不是 null
是正确的,我认为如果你的从堆栈中获取 args,当从堆栈中获取 args 时,您应该检查 0。
第二:对于大于 255 的数字,
echo $
?会给我错误的结果,但这没关系,因为echo $
?只能显示最多 255 的数字,因此即使 echo 可能显示错误的数字,寄存器 rbx 仍保存正确的值。我调试了它,现在工作正常。
FIXED:
I found out what was wrong with the program =D
First of all you need to check for value 10 so
is wrong because were looking for the new line ascii code not a null
is right, I don't think it works if your getting the args from the stack, when getting args from stack you should check for 0.
Second: For numbers bigger than 255,
echo $
? would give me wrong results, but that's ok becauseecho $
? can only show numbers up to 255, so even tho echo may show a wrong number the register rbx holds the right value.I debugged it and it works fine now.