俺啥也不懂-不知道什么时候才会编写操作系统-一个hello world写一年-最终还是逃不过gdb调试

俺啥也不懂-不知道什么时候才会编写操作系统-一个hello world写一年-汇编如何计算字符串的长度

上一篇文章纠结了好久,其实俺其实可以继续学习后面的东西,很多人hello world写完了直接就开始进入保护模式了,但是俺想了想还是停下来了,把没搞明白的地方继续搞明白,这其实是汇编基础了,基础差还是愁人

今天就讲cmp byte[eax],0和jz指令,本来不想搞gdb的,最终还是妥协了,看不懂就得调试。

cmp命令得出的结果其实是byte[eax]-0的结果,jz的意思是jmp if zero,即结果为0时跳转,至于cmp影响标志位,还是不讲,注意的是cmp不改变eax的值,而bypte[eax]的意思是eax指向内存地址的值。

先看hello word代码,这里的字符串长度我改成了两个,方便调试

SECTION .data
msg db 'he'
SECTION .text
global main
main:
	mov ebx,msg
	mov eax,ebx
nextchar:
	cmp byte[eax],0
	jz  finished
	inc eax
	jmp nextchar
finished:
	sub eax,ebx
	mov edx,eax
	mov ecx,msg
	mov ebx,1
	mov eax,4
	int 80h

	mov ebx,0
	mov eax,1
	int 80h

编译和链接用的命令:

nasm -f elf64 -g hello.asm

gcc -g -o main hello.o

注意,这里的-g必须要带上,gdb调试需要这个标志,不然就是无法调试了。

gdb的调试命令不讲了,各位自行搜索。

下面看调试结果,这里因为我编译的时候是64位,所以我的寄存器是rax。

[root@localhost lesson3]# gdb main
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-119.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/local/myAll/study/huibian/lesson3/main...done.
(gdb) delete breakpoints
(gdb) r
Starting program: /usr/local/myAll/study/huibian/lesson3/main 
he[Inferior 1 (process 7390) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-307.el7.1.x86_64
(gdb) list
1       SECTION .data
2       msg db 'he'
3       SECTION .text
4       global main
5       main:
6               mov ebx,msg
7               mov eax,ebx
8       nextchar:
9               cmp byte[eax],0
10              jz  finished
(gdb) b 9
Breakpoint 1 at 0x4004d7: file lesson3.asm, line 9.
(gdb) r
Starting program: /usr/local/myAll/study/huibian/lesson3/main 

Breakpoint 1, 0x00000000004004d7 in nextchar ()
(gdb) p/x $rax
$1 = 0x601024
(gdb) c
Continuing.

Breakpoint 1, 0x00000000004004d7 in nextchar ()
(gdb) p/x $rax
$2 = 0x601025
(gdb) b 14
Breakpoint 2 at 0x4004e1: file lesson3.asm, line 14.
(gdb) c
Continuing.

Breakpoint 1, 0x00000000004004d7 in nextchar ()
(gdb) p/x $rax
$3 = 0x601026
(gdb) x/20cb 0x601026
0x601026 <completed.6355>:      0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
0x60102e:       0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
0x601036:       0 '\000'        0 '\000'        0 '\000'        0 '\000'
(gdb) c
Continuing.

Breakpoint 2, 0x00000000004004e1 in finished ()
(gdb) c
Continuing.
he[Inferior 1 (process 7394) exited normally]
(gdb) r
Starting program: /usr/local/myAll/study/huibian/lesson3/main 

Breakpoint 1, 0x00000000004004d7 in nextchar ()
(gdb) p/x $rax
$4 = 0x601024
(gdb)  x/20cb 0x601024
0x601024 <msg>: 104 'h' 101 'e' 0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
0x60102c:       0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
0x601034:       0 '\000'        0 '\000'        0 '\000'        0 '\000'
(gdb) c
Continuing.

Breakpoint 1, 0x00000000004004d7 in nextchar ()
(gdb) c
Continuing.

Breakpoint 1, 0x00000000004004d7 in nextchar ()
(gdb) c
Continuing.

Breakpoint 2, 0x00000000004004e1 in finished ()
(gdb) c
Continuing.
he[Inferior 1 (process 7395) exited normally]
(gdb) ^CQuit
(gdb) 

俺把断电打在了第9行:b 9就是打断点的命令

r是run命令

p/x $rax查看rax的内存地址:0x601024

x/20cb 0x601024查看内存值:

0x601024 <msg>: 104 'h' 101 'e' 0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
0x60102c:       0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
0x601034:       0 '\000'        0 '\000'        0 '\000'        0 '\000'

包括了104h和101e,大家自行查ascii码表

c是continue的意思,俺又在14行下了断点,连续执行c之后,当断点指向sub eax,ebx的时候,查看rax的内存地址:0x601026

查看rax内存值:x/20cb 0x601026

0x601026 <completed.6355>:      0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
0x60102e:       0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'        0 '\000'
0x601036:       0 '\000'        0 '\000'        0 '\000'        0 '\000'

连续inc ax后,rax指向地址的内存值变为0,即byte[rax]的值变为0,也证实了Zero is an end of string delimiter。

咱们实现的一直是黑底红字的hello world,下次搞个黑底绿字的吧

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值