乱码三千 – 分享实用IT技术

乱码三千 – 码出一个新世界


  • 首页

  • 归档

  • 搜索

8086汇编语言之数据段和代码段以及栈段的理解

发表于 2020-11-01

数据段DS+偏移地址段BX

数据段可以通俗理解为数据容器指针

比如:

1
2
3
4
5
MOV AX 0220H
MOV DS AX
MOV BX 0
MOV AX [BX]
;我们发现 DS数据段一直都是在给不同地址的容器赋值

代码段CS+偏移地址段IP

代码段可以通俗理解为汇编代码指针

比如:

代码从 MOV AX 0220H 开始,那么代码段指向这行代码地址, 如果想要跳过这行代码的执行,那么进行代码段偏移

在通过debug模式配合-u指令查看汇编代码时,可以根据CS进行范围查看:

比如:

1
2
3
4
5
6
#以下模拟控制台输出
-r
AX=0000 BX=0000.....
DS=13DB ES=13DB SS=13EB CS=13EB IP=0000
-u 13eb:0
13BE:0000 B8FFFF MOV AX,FFFF

栈段SS+偏移地址段SP

栈段可以通俗理解为栈指针

什么是段

首先内存并没有分段,段的划分来自CPU,来自我们自己对内存的操作。由8086CPU

1
(段地址+偏移地址=“物理地址”)

的方式给出内存单元的物理地址,使得我们用分段的方式管理内存

可以将段通俗理解为小区的一栋楼,偏移地址为这栋楼的住户门牌号.比如五号楼101房,那么形象比喻:

1
五号楼---->段地址  101房---->偏移地址

为什么要这样划分?

直接使用一个物理地址岂不是更简单,何必拆分成段地址+物理地址?

这是由于8086cpu16位寄存器局限性造成的, 由于16位的寄存器最大只能存放0xFFFF 如果存放超过五位的地址比如0xFFFFA 则无法存放, 为了解决这个问题, cup设计者想出了 段地址*16+偏移地址的方法完美解决这个问题

物理地址=段地址*16+偏移地址

一个物理地址可以有四种写法, 比如0xFFFFA:

1
2
3
4
5
6
7
0xFFFFA=0xFFFF0*16+0x000A

0xFFFFA=0xFFF00*16+0x00FA

0xFFFFA=0xFF000*16+0x0FFA

0xFFFFA=0xF0000*16+0xFFFA

段的赋值

代码段CS 数据段DS 栈段SS 不能直接赋值, 必须通过通用寄存器中转赋值

偏移地址可以直接赋值

1
2
3
mov ax ,2000H
mov ss ,ax
mov sp ,10H

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

8086汇编语言之各个通用寄存器的作用

发表于 2020-11-01

在8086cpu通用寄存器

  • 寄存器AX: 用于存放数据 (源代码编写时不能以字母开头,可在开头补上0)
    • 比如 mov ax, ffffh 应该写成 mov ax, 0ffffh 否则编译报错
  • 寄存器BX: 另外还用于存放数据段偏移地址 初始值为源代码大小
  • 寄存器CX: 另外还用于存放loop循环计数
  • 寄存器DX: 另外还用于存放累加结果
  • 寄存器EX:备用寄存器

## BX存在的意义

1. asm编译器无法识别中括号,mov ax,[0]编译时会默认去除中括号.使用bx替代可以解决这个问题,如果在debug模式下使用-a命令输入中括号则没有问题,可以正常识别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;错误写法:编译器无法识别[0],会直接取值为0 而不是偏移地址0所对应的内容
assumme cs:code
code segment
mov ax,2000h
mov ds,ax
mov al,[0]
mov bl,[1]
mov cl,[2]
mov dl,[3]

mov ax,4c00h
int 21h
code ends
end

问题: 那如果非要以带中括号的方式进行编写可以吗? 答案是:需要带上段地址ds,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
assumme cs:code
code segment
mov ax,2000h
mov ds,ax
mov al,ds:[0] ;其中ds称作段前缀
mov bl,ds:[1]
mov cl,ds:[2]
mov dl,ds:[3]

mov ax,4c00h
int 21h
code ends
end

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

8086语言之申请栈空间的方法

发表于 2020-11-01

第一种

使用dw或者db直接申请

1
2
3
4
5
6
7
assume cs:cscode
cscode segment
dw 0,0,0,0,0,0,0,0 ;定义8个字型数据,在程序加载后,将取得8个字的内存空间,可当做栈空间使用
start:mov ax,cs
...
cscode ends
end start

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

汇编语言之debug模式常用指令介绍

发表于 2020-11-01

在搭建好了8086汇编的开发环境后,接下来介绍8086的debug模式。执行debug.exe以进入debug调试模式,在dos中通过输入命令的方式进行交互

## -R命令

R命令的作用是查看和修改debug模式下CPU中寄存器的值

## -D命令

D命令的作用是查看内存中的内容

上面为(段地址:偏移地址)查看方式。D命令默认会显示寻址地址开始的后128个内存单元的内容,以16进制的方式显示(每个内存单元8位,一行最多16个内存单元),而最右边会将内存单元中的二进制数据以ascll码的形式翻译展示

  但有时,我们只想聚焦于某一部分内存地址的内容,而默认展示的内存视图不是很方便。

  D命令提供了另外一种访问内存的方式(段地址:偏移起始地址 偏移终止地址),其能够展示(段地址:偏移起始地址 至 段地址:偏移终止地址)的内存信息,范围两端均为闭区间

-E命令

E命令的作用是改变内存中的内容。

 和对CPU中寄存器的查看,修改不同,对内存进行查看和修改较为复杂,为此debug设计了两个不同的命令分别进行控制(E命令修改内存、D命令查看内存)。

  通过(E 起始地址 数据1 数据2 数据3…)命令可以修改内存中以起始地址开始,顺序的N个内存单元的值(N为实际参数传递的数量)

也可以和R命令修改CPU中寄存器值类似的,通过提示来修改特定内存单元的值。00.12 00代表内存单元在修改前的值,12是我们手动输入的、需要修改的新值

-U命令

U命令的作用是将内存中的二进制数据转换为汇编指令展示(反汇编)

D命令能够将内存中的数据以16进制或ascll码的形式展现出来,但有时我们需要观察的是内存中的机器指令时,D命令的视图过于抽象,不利于理解。debug提供了U命令来解决这个问题。

  对于前面我们在1000:0处输入的机器指令,使用 U 1000:0 命令(u 内存地址)可以将内存中的数据以汇编语言指令的方式进行展示

-A命令

A命令能够以汇编指令的形式向内存中写入内容

对于内存操作,D命令可以查看内存中的内容,但如果想查看的是程序指令,显然U命令更加方便;E命令可以向内存中写入数据,但对于程序指令的写入,直接操作二进制机器码的方式过于硬核。为此,debug提供了A命令,我们可以通过A命令以汇编指令的形式向内存中写入内容。

  通过A命令将(mov ax,0001,mov bx,0002,add ax,bx)三条指令写入内存1000:0处:

通过A命令进行指令的写入,和E命令达到的效果一样,但使用起来却更加便捷。A命令能够自动识别所输入汇编指令的长度,正确的在内存中写入程序指令。

  debug提供了D、E两种命令用于对内存进行通用的操作(纯二进制、十六进制数据的读、写)。

  对于程序指令,debug提供了U、A两种命令以更人性化的方式来读写内存中的指令内容

-T命令

 T命令的作用是进行单步机器指令的调试

-G命令

 G命令的作用是进行Debug程序断点调试

1
-g 代码地址(cs+ip)地址

-p命令

 p命令的作用是断点跳过执行 ,可用于循环调试

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

java和smali语言互转流程图

发表于 2020-11-01

baksmali和smali.jar工具下载

https://bitbucket.org/JesusFreke/smali/downloads/

点此下载

.class转dex指令

1
dx.bat --dex --output=./aa.dex Test.class

dex转smali指令

1
java -jar baksmali-2.4.0.jar d test.dex

smali转dex指令

1
java -jar smali-2.4.0.jar a smali文件或目录 -o 输出目录/xxx.dex

dex转class指令

1
d2j-dex2jar.bat xxx.dex

class转java

  1. 直接使用jad-gui或者jadx
  2. 使用javap -p xxx.class查看

另外

  1. 如果你嫌麻烦 可以直接使用dex2jar内部的工具 里面进行了相应的封装

  2. android studio自带的.class转smali就非常好用,如图:

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

关于十六进制和二进制左移位右移位的问题

发表于 2020-10-30

Step 1

先聊十进制

以10举例:(满10进一位)

  • 10往左移一位变成100, 可以理解为是10乘以10得来的,100=10x10
  • 10往右移一位变成1, 可以理解为是10除以10得来的,1=10/10

那么十六进制

以2F0举例:(满16进一位)

  • 2F0往左移一位变成2F00, 可以理解为是2F0乘以16得来的
  • 2F0往右移一位变成2F, 可以理解为是2F0除以16得来的

二进制同理

以1010举例:(满2进一位)

  • 1010往左移一位变成10100, 可以理解为是1010乘以2得来的,20=10x2(需要换算成十进制进行计算)
  • 1010往右移一位变成101, 可以理解为是1010除以2得来的,5=10/2

总结

  • 向左移位低位进位补0,向右移位低位去0
  • 十进制满10进位,十六进制满16进位,八进制满8进位,二进制满2进位
  • 二进制每四位分割对应一个16进制,每三位分割对应一个八进制

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Code Spring Boot Project With Kotlin by Android Studio

发表于 2020-10-30

Step 1

Modify build.gradle

  1. In Module Dir : apply plugin: ‘kotlin’ and add kotlin dependencies
1
2
3
4
5
6
7
8
9
10
11
apply plugin: 'org.springframework.boot'
apply plugin: 'java'
apply plugin: 'kotlin'//notice


dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
compile 'org.springframework.boot:spring-boot-starter:2.3.4.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-web:2.3.4.RELEASE'
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72"//notice
}
  1. Project Dir : add kotlin classpath
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
buildscript {
ext {
springBootVersion = '1.5.9.RELEASE'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72"//notice
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

Step 2

  1. Code with kotlin

    tip: if you use pure kotlin, you may code in kotlin dir replace java

Step 3

Done!

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Create Spring Boot Project With Android Studio

发表于 2020-10-30

Step 1

Modify build.gradle

  1. Module Dir
1
2
3
4
5
6
7
8
9
apply plugin: 'org.springframework.boot'
apply plugin: 'java'


dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
compile 'org.springframework.boot:spring-boot-starter:2.3.4.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-web:2.3.4.RELEASE'
}
  1. Project Dir
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

buildscript {
ext {
springBootVersion = '1.5.9.RELEASE'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

Step 2

  1. Rename Res dir And create application.properties
  2. delete useless files

Step 3

  1. Create Boot Point Class DemoApplication.java

  2. Create Control

  3. Boot And Test

  4. Package Jar

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

python中的base64加密解密

发表于 2020-10-29

介绍

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。

Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。

python中的base64

将url编码成base64

1
2
3
4
5
6
7
# 想将字符串转编码成base64,要先将字符串转换成二进制数据
url = "https://www.cnblogs.com/songzhixue/"
bytes_url = url.encode("utf-8")
str_url = base64.b64encode(bytes_url) # 被编码的参数必须是二进制数据
print(str_url)

b'aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vc29uZ3poaXh1ZS8='

解码base64

1
2
3
4
5
6
7
# 将base64解码成字符串
import base64
url = "aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vc29uZ3poaXh1ZS8="
str_url = base64.b64decode(url).decode("utf-8")
print(str_url)

'https://www.cnblogs.com/songzhixue/'

总结

  • python中base64不论是编码还是解码,返回值都为字节数组
  • 解码解的是字符串, 编码编的是字节数组

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

python字符串str和字节数组相互转化

发表于 2020-10-29

字符串转字节数组

1
2
3
4
5
6
7
s = "Hello, world!"   # str object 

#一共有三种方式 任选其一
print('str --> bytes')
print(bytes(s, encoding="utf8"))
print(str.encode(s)) # 默认 encoding="utf-8"
print(s.encode()) # 默认 encoding="utf-8"

字节数组转字符串

1
2
3
4
5
6
7
b = b"Hello, world!"  # bytes object  

#一共有三种方式 任选其一
print('\nbytes --> str')
print(str(b, encoding="utf-8"))
print(bytes.decode(b)) # 默认 encoding="utf-8"
print(b.decode()) # 默认 encoding="utf-8"

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

1…323334…50

乱码三千

android程序员一枚,擅长java,kotlin,python,金融投资,欢迎交流~

491 日志
143 标签
RSS
© 2025 乱码三千
本站总访问量次
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
0%