A. 如何编写完整的汇编程序
看很多资料的话就应该懂得写啊,先看那个王爽的书咯,到第四章差不多就会写了。努力啊
B. 如何用汇编编写以下程序
一个汇编程序是由多个段组成的,这些段被用来存放代码、数据或当作栈空间来使用。
一个有意义的汇编程序中至少要有一个段,这个段用来存放代码。
程序结束标记
End 是一个汇编程序的结束标记,编译器在编译汇编程序的过程中,如果碰到了伪指令 end,就结束对源程序的编译。
如果程序写完了,要在结尾处加上伪指令end 。否则,编译器在编译程序时,无法知道程序在何处结束。
C. 请高手解释下汇编语言的代码段和程序段的具体定义和变量的定义方法,有离子的最好.
代码段和程序段定义的名字可以任意,只是代码段会被执行,由最后的end +标号指出起始标号 以汤叔的程序为例
SixteenBits DW 12345
这句话定义了一个16位的变量 sixteenbits
定义格式 变量名+长度+初值
段定义方式
不加描述符的最简单的段定义
段名+segment 后以段明+ends表明段结束
在下面这个程序里 data段是数据段 code段是代码段
Assume CS:Code,DS:Data 这条伪指令指定段的关联寄存器
; 本程序通过编译,运行正确。
Data Segment
SixteenBits DW 12345
Data Ends
Code Segment
Assume CS:Code,DS:Data
Start: mov ax,Data ;取数据段地址
mov ds,ax ;赋给数据段寄存器ds
mov ax,SixteenBits
push cs
pop ds
lea di,binary ;二进制字符串首地址
mov cx,16 ;移位次数
cld
push di
; 转换成二进制字符串
Shift_Left: sal ax,1 ;算术左移
jc Carry_Yes ;有进位,跳转
mov byte ptr [di],'0' ;无进位
jmp Next_Bit
Carry_Yes: mov byte ptr [di],'1' ;有进位
Next_Bit: inc di
loop Shift_Left
mov byte ptr [di],'$' ;字符串结束符
pop dx
; 显示二进制字符串
mov ah,9
int 21h
Exit_Proc: MOV AX,4C00H ;结束程序
INT 21H
binary:
Code ENDS
END Start ;编译到此结束
D. 汇编中的程序段的概念
汇编中的程序段是指通过一个段寄存器给出的段地址和以某种方式给出的偏移地址组合所能直接访问的一段内存。为方便对存储器的访问,数据、程序等等均放在各自的段寄存器所能方便控制访问的存储器区域中(程序段中)。在程序段中,能存放多个子程序。
E. 汇编程序段中数据段的定义
DATASEGMENT
STR1DB'whatisyourname?',13,10,'$'
CNEQU$-STR1
STR2EQUSTR1+CN-5
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA,ES:DATA
START:MOVAX,DATA
MOVDS,AX
MOVES,AX
MOVDX,OFFSETSTR1
MOVAH,9
INT21H
MOVSI,OFFSETSTR1
MOVDI,OFFSETSTR2
MOVCX,CN
ADDSI,CN-1
ADDDI,CN-1
STD
REPMOVSB
MOVDX,OFFSETSTR2
INT21H
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
教材中有详细的介绍,请认真阅读,多复习。
es是附加数据段段地址,程序中是将数据段和附加数据段同段。
str1是21个字节。
cn和str2在这里都是常量。
数据段中只定义了存储区str1。(但又将str2当存储区使用,这种用法少见,不要学!)
============================================================
以上操作的问题,str2并未申请缓冲区,在执行时有越界的风险!
============================================================
以下是规范的程序:
DATASEGMENT
STR1DB'whatisyourname?',13,10,'$'
CNEQU$-STR1
STR2DBCNDUP(?)
DATAENDS
CODESEGMENT
ASSUMECS:CODE,DS:DATA,ES:DATA
START:MOVAX,DATA
MOVDS,AX
MOVES,AX
LEADX,STR1
MOVAH,9
INT21H
LEASI,STR1
LEADI,STR2
MOVCX,CN
ADDSI,CN-1
ADDDI,CN-1
STD
REPMOVSB
LEADX,STR2
INT21H
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
F. GNU 汇编: 第一个汇编程序
汇编语言程序由定义好的段构成, 每个段都有不同的目的, 最常用的三个段如下
.section 命令语句可声明段, .section 语句只有一个参数, 这个参数用来声明段的类型.
获取 cupid 的程序: demo.s
gcc 标签识别 main 标签, 更改 _start 为 main 然后执行:
如果使用的是 WSL, 64位的 WSL 环境默认无法编译运行32位程序, 可通过如下方案运行 (参考 https://github.com/Microsoft/WSL/issues/2468 ):
G. 汇编段定义语句
END START 这行有两个作用:一是告诉汇编程序,本源程序结束,汇编到此为止;二是告诉汇编程序,本程序的入口地址在start这个标号所在处。只有主程序所在的源文件中的END后才需要加start之类的标号。其他的非主程序所在的源文件最后的end后是不需要加上start之类的标号的。
H. 一个完整的汇编程序至少需要定义一个段,即____段
一个完整的汇编程序至少需要定义一个段,即 代码 段.
[80x86汇编语言程序设计教程]有提及这句话:
"通常情况下,代码和数据分别在代码段和数据段中,但有时代码和数据可以合并在一个段中.一个完整的汇编语言源程序至少含有一个代码段,但一个汇编语言源程序模块却可以只有数据段.目前,我们总把数据段安排在程序的前面,把代码段安排在程序的后面,但不是非要这样安排."
I. 汇编语言子程序是如何定义的
这样定义的:
子程序名 PROC NEAR|FAR
.
.
RET
子程序名 ENDP
子程序名相当于标号,表示本过程的符号地址。过程有NEAR和FAR两种类型,FAR型的过程可供段间调用,NEAR型过程仅供段内调用。
在一个过程中,至少要有一条返回指令RET,它可以书写在过程中的任何位置,但是过程执行的的最后一条指令一定是RET。
注意事项
一、子程序调用指令
格式:CALL [NEAR PTR] 子程序名
CALL指令的两个作用,1.将断点地址(CALL指令的下一条指令地址)压栈保存,2.转去子程序执行。
[NEAR PTR]可以省略。
二、返回指令
格式:RET [N]
指令作用:实现子程序执行完后返回主程序的指令。从堆栈栈顶弹出一个字数据(段内调用)送入IP作为返回地址。N是立即数,执行完RET之后,再将SP增加N,也叫“平栈”。
J. 如何编写最简单的汇编语言
了解计算机CPU原理:详情请参照“80X86计算机组织”和“80X86的指令系统和寻址方式”
求表达式Y=A*X+B-C的值,已知A、B、C分别存放在DA-1、DA-2、DA-3字节单元,它们的值分别是:5 、 6、 7,X存放在INPUT字节单元,结果Y放入jsJ_10字节单元。
分析顺序结构程序代码:由记事本敲出来的
data segment da_1 db 5 da_2 db 6 da_3 db 7 input db 1 jsj_10 db 0data ends ;这一段在内存中定义了一个段,叫做data,并且其中存入了5个变量并且付入初值,db代表每个变量占用1个字节,若是dd则为字,为2个字节code segment ;名字叫做code的段的定义,显然这儿作为代码段,当然code这个名字可以更改 assume cs:code,ds:data ;指定data为DS数据段,code为CS代码段start: mov ax,data ;加法指令 mov ds,ax ;加法指令 mov al,da_1 ;加法指令
mov bl,input ;加法指令
mul bl ;乘法 add al,da_2 sub al,da_3 ;减法 mov jsj_10,al
exit: mov ah,4ch int 21h ;这两行相当于ret(返回值),就像C语言中的return 0;
code ends end start
注释: XXXX segment
.............
XXXX ends ;定义一个段
assume ds:XXXX 把XXXX段指定为ds(ds是段地址寄存器)
请先提前把masm edit debug link文件放入预定的文件夹,并把编写的xxxx.asm代码文件放入该文件夹,asm文件可用记事本写成,并改格式txt为asm(有的看不到文件后缀.txt的请参照网络)